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…