iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Navbars

A handful of navbar patterns built with Tailwind utilities — a desktop top bar with dropdown, a mobile slide-over, a sticky translucent bar with backdrop blur. Each works in light + dark mode and does not require a JS framework beyond a tiny disclosure.

Four navbar patterns + a mobile sheet

EXAMPLE
<!-- 1) Top bar with logo, links, primary action -->
<header class='border-b bg-white/90 backdrop-blur dark:border-slate-700 dark:bg-slate-900/80
                supports-[backdrop-filter]:bg-white/70 dark:supports-[backdrop-filter]:bg-slate-900/60'>
  <div class='mx-auto flex h-14 max-w-6xl items-center gap-4 px-4'>
    <a href='/' class='font-semibold tracking-tight'>Shop</a>
    <nav class='hidden gap-1 md:flex'>
      <a href='/products' class='rounded px-3 py-1.5 text-sm hover:bg-slate-100 dark:hover:bg-slate-800'>Products</a>
      <a href='/pricing'  class='rounded px-3 py-1.5 text-sm hover:bg-slate-100 dark:hover:bg-slate-800'>Pricing</a>
      <a href='/blog'     class='rounded px-3 py-1.5 text-sm hover:bg-slate-100 dark:hover:bg-slate-800'>Blog</a>
    </nav>
    <div class='ml-auto flex items-center gap-2'>
      <a href='/login' class='hidden text-sm md:block'>Sign in</a>
      <a href='/signup'
         class='rounded-lg bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700'>
        Start trial
      </a>
      <!-- Mobile menu trigger; details/summary needs zero JS -->
      <details class='relative md:hidden'>
        <summary class='list-none rounded p-2 hover:bg-slate-100 dark:hover:bg-slate-800'>
          <span class='sr-only'>Open menu</span>
          <svg class='h-5 w-5' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'>
            <path d='M3 6h18M3 12h18M3 18h18' />
          </svg>
        </summary>
        <ul class='absolute right-0 top-full mt-2 w-44 rounded-md border bg-white p-1 shadow
                    dark:border-slate-700 dark:bg-slate-900'>
          <li><a href='/products' class='block rounded px-3 py-2 text-sm hover:bg-slate-100 dark:hover:bg-slate-800'>Products</a></li>
          <li><a href='/pricing'  class='block rounded px-3 py-2 text-sm hover:bg-slate-100 dark:hover:bg-slate-800'>Pricing</a></li>
          <li><a href='/blog'     class='block rounded px-3 py-2 text-sm hover:bg-slate-100 dark:hover:bg-slate-800'>Blog</a></li>
        </ul>
      </details>
    </div>
  </div>
</header>

<!-- 2) Dropdown using <details> — no JS, accessible by default -->
<details class='relative inline-block'>
  <summary class='cursor-pointer list-none rounded px-3 py-1.5 text-sm hover:bg-slate-100'>Account ▾</summary>
  <ul class='absolute right-0 mt-2 w-48 rounded-md border bg-white p-1 shadow'>
    <li><a href='/profile' class='block rounded px-3 py-2 text-sm hover:bg-slate-100'>Profile</a></li>
    <li><a href='/orders'  class='block rounded px-3 py-2 text-sm hover:bg-slate-100'>Orders</a></li>
    <li><hr class='my-1' /></li>
    <li><a href='/logout'  class='block rounded px-3 py-2 text-sm hover:bg-slate-100'>Sign out</a></li>
  </ul>
</details>

<!-- 3) Sticky, scroll-aware translucent bar -->
<header class='sticky top-0 z-40 border-b bg-white/70 backdrop-blur
                dark:bg-slate-900/60 dark:border-slate-700'>
  <!-- contents from snippet 1 -->
</header>

<!-- 4) Brand + search + actions row -->
<header class='border-b bg-white dark:bg-slate-900 dark:border-slate-700'>
  <div class='mx-auto flex h-16 max-w-7xl items-center gap-4 px-4'>
    <a href='/' class='font-semibold'>Catalog</a>
    <div class='ml-auto hidden md:block'>
      <label class='relative block'>
        <span class='sr-only'>Search</span>
        <input type='search' placeholder='Search products...'
               class='w-72 rounded-md border bg-slate-50 px-3 py-1.5 pl-9 text-sm
                       focus:outline-none focus:ring-2 focus:ring-blue-500
                       dark:bg-slate-800 dark:border-slate-700' />
        <svg class='absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-400' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'>
          <circle cx='11' cy='11' r='7' />
          <path d='m20 20-3-3' />
        </svg>
      </label>
    </div>
    <a href='/cart' class='ml-2 rounded p-2 hover:bg-slate-100 dark:hover:bg-slate-800'>
      <svg class='h-5 w-5' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'>
        <path d='M6 6h15l-1.5 9h-12z' />
        <circle cx='9' cy='20' r='1.5' />
        <circle cx='18' cy='20' r='1.5' />
      </svg>
    </a>
  </div>
</header>

<!-- 5) Active link styling — for SPA frameworks
     React Router: NavLink className=({ isActive }) => isActive ? 'font-semibold' : ''
     Vue Router:   active-class='font-semibold'
     Svelte:       compare $page.url.pathname === '/foo' -> bold class
     Tailwind side: keep the class string unchanged across the framework.
-->

<!-- 6) Pitfalls -->
<!-- - Putting a sticky element inside an overflow: hidden ancestor (the sticky stops working) -->
<!-- - Forgetting z-index high enough above modals / overlays -->
<!-- - Backdrop blur without supports-[backdrop-filter]:bg-* fallback -->
<!-- - Mobile menu that traps focus poorly (use real <button> + <dialog> for accessibility on big menus) -->
<!-- - Search input without 'label' + 'aria-label' / sr-only label -->

Why it matters

`

` and `` cover most dropdown and mobile menu needs without a single line of JS — they handle keyboard, focus, and ARIA states by default. Reach for a JS disclosure component only when you need controlled state (close on outside click, animate the panel); for plain navbar dropdowns, the HTML element is the simplest right answer.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
<nav class="flex items-center gap-6 px-4 py-3 bg-slate-900 text-white">…</nav>
Try it Yourself »

Discussion

Loading…