A Responsive Navbar with Mobile Menu
Build a sticky app bar with a desktop menu and a JavaScript-free mobile drawer.
A navbar exercises almost every layout tool at once: flex distribution, responsive show/hide, sticky positioning, and a mobile toggle. Here is the pattern that scales.
The desktop skeleton
flex items-center justify-between puts the logo on the left and links on the right. The link cluster is hidden md:flex — gone on phones, visible from md up.
The sticky treatment
sticky top-0 z-40 keeps it pinned; backdrop-blur plus a translucent background (bg-white/80) and a hairline border-b give that modern frosted app-bar feel.
A mobile menu with no script
A hidden checkbox is the switch, a label is the hamburger, and the peer variant reveals the panel:
<input id="nav" type="checkbox" class="peer hidden">
<label for="nav" class="md:hidden">☰</label>
<div class="hidden peer-checked:block md:hidden">…links…</div>Example
When to use it
- A marketing site uses a sticky navbar that collapses its links into a slide-down mobile menu, toggled with a single JS class add/remove and styled entirely with Tailwind.
- A web app shell features a top bar with the company logo on the left, primary navigation links centered, and user-avatar + notification icon on the right, all using flex distribution utilities.
- A documentation site renders a persistent header with a search input that expands on focus and hides on small screens via hidden/md:flex, keeping the mobile layout clean.
More examples
Desktop navbar with flex layout
Uses hidden md:flex to show desktop links only, and md:hidden to show the hamburger only on mobile, without any CSS media-query hand-coding.
<nav class="sticky top-0 z-50 bg-white shadow-sm">
<div class="max-w-6xl mx-auto px-4 flex items-center justify-between h-16">
<a href="/" class="text-xl font-bold text-cyan-600">Brand</a>
<ul class="hidden md:flex items-center gap-8 text-sm font-medium text-gray-600">
<li><a href="#" class="hover:text-cyan-600 transition-colors">Products</a></li>
<li><a href="#" class="hover:text-cyan-600 transition-colors">Pricing</a></li>
<li><a href="#" class="hover:text-cyan-600 transition-colors">About</a></li>
</ul>
<a href="#" class="hidden md:block px-4 py-2 rounded-lg bg-cyan-600 text-white text-sm font-semibold hover:bg-cyan-700">Sign up</a>
<button id="menu-btn" class="md:hidden p-2 rounded text-gray-600 hover:bg-gray-100">☰</button>
</div>
</nav>Mobile drawer panel
The mobile menu is a separate block toggled by a single classList.toggle('hidden') — no custom CSS, just Tailwind's hidden utility.
<div id="mobile-menu" class="hidden md:hidden bg-white border-t border-gray-100 px-4 pb-4">
<ul class="flex flex-col gap-2 mt-2 text-sm font-medium text-gray-700">
<li><a href="#" class="block py-2 px-3 rounded hover:bg-gray-50">Products</a></li>
<li><a href="#" class="block py-2 px-3 rounded hover:bg-gray-50">Pricing</a></li>
<li><a href="#" class="block py-2 px-3 rounded hover:bg-gray-50">About</a></li>
<li class="pt-2">
<a href="#" class="block w-full text-center py-2 rounded-lg bg-cyan-600 text-white font-semibold hover:bg-cyan-700">Sign up</a>
</li>
</ul>
</div>
<script>
document.getElementById("menu-btn").addEventListener("click", () =>
document.getElementById("mobile-menu").classList.toggle("hidden"));
</script>Navbar with active link and user avatar
Shows an active link styled with border-b-2 border-cyan-400, a notification dot using absolute positioning, and a ringed avatar — all common app-shell patterns.
<nav class="sticky top-0 z-50 bg-gray-900 text-white">
<div class="max-w-6xl mx-auto px-4 flex items-center justify-between h-14">
<a href="/" class="text-lg font-bold tracking-tight">AppName</a>
<ul class="hidden md:flex items-center gap-6 text-sm">
<li><a href="#" class="text-gray-400 hover:text-white transition-colors">Dashboard</a></li>
<li><a href="#" class="text-white border-b-2 border-cyan-400 pb-0.5">Projects</a></li>
<li><a href="#" class="text-gray-400 hover:text-white transition-colors">Settings</a></li>
</ul>
<div class="flex items-center gap-3">
<button class="relative p-2 text-gray-400 hover:text-white">
<span class="text-lg">🔔</span>
<span class="absolute top-1 right-1 w-2 h-2 rounded-full bg-red-500"></span>
</button>
<img src="avatar.jpg" alt="User" class="w-8 h-8 rounded-full object-cover ring-2 ring-cyan-400" />
</div>
</div>
</nav>
Discussion