Nav Bars
Sticky top nav
Logo, links, and CTA
Logo, links, and CTA
Build a sticky top navigation bar with Tailwind CSS: a translucent, blurred, bordered bar. Left: logo mark + wordmark. Center/right: horizontal nav links (hidden on mobile). Far right: a ghost "Sign in" link and a solid "Get started" button. Include a hamburger button that appears below md, and a collapsed mobile panel underneath repeating the links and actions. Then add JavaScript to make the hamburger work: toggle the panel, swap the icon between bars and an X, keep aria-expanded and aria-controls honest, close the panel when a link inside it is tapped or when Escape is pressed, and close it automatically if the viewport grows past the md breakpoint while it is open. <header class="sticky top-0 z-50 border-b border-neutral-200 bg-white/80 backdrop-blur">
<nav class="mx-auto flex max-w-6xl items-center justify-between px-6 py-3.5">
<a href="#" class="flex items-center gap-2 font-semibold text-neutral-900">
<span class="h-6 w-6 rounded-md bg-neutral-900"></span> Nimbus
</a>
<div class="hidden items-center gap-8 text-sm text-neutral-600 md:flex">
<a href="#" class="hover:text-neutral-900">Product</a>
<a href="#" class="hover:text-neutral-900">Solutions</a>
<a href="#" class="hover:text-neutral-900">Pricing</a>
<a href="#" class="hover:text-neutral-900">Docs</a>
</div>
<div class="hidden items-center gap-3 md:flex">
<a href="#" class="text-sm font-medium text-neutral-600 hover:text-neutral-900">Sign in</a>
<a href="#" class="rounded-lg bg-neutral-900 px-4 py-2 text-sm font-medium text-white hover:bg-neutral-800">Get started</a>
</div>
<button id="menuBtn" class="md:hidden" aria-label="Menu" aria-expanded="false" aria-controls="mobileMenu">
<svg id="menuIcon" class="h-6 w-6 text-neutral-900" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" d="M4 6h16M4 12h16M4 18h16"/></svg>
</button>
</nav>
<div id="mobileMenu" class="hidden border-t border-neutral-200 px-6 py-4 md:hidden">
<div class="flex flex-col gap-3 text-sm text-neutral-600">
<a href="#" class="hover:text-neutral-900">Product</a>
<a href="#" class="hover:text-neutral-900">Solutions</a>
<a href="#" class="hover:text-neutral-900">Pricing</a>
<a href="#" class="hover:text-neutral-900">Docs</a>
</div>
<div class="mt-4 flex items-center gap-3 border-t border-neutral-100 pt-4">
<a href="#" class="text-sm font-medium text-neutral-600 hover:text-neutral-900">Sign in</a>
<a href="#" class="rounded-lg bg-neutral-900 px-4 py-2 text-sm font-medium text-white hover:bg-neutral-800">Get started</a>
</div>
</div>
</header> var BARS = "M4 6h16M4 12h16M4 18h16";
var CROSS = "M6 6l12 12M18 6L6 18";
var button = document.getElementById("menuBtn");
var menu = document.getElementById("mobileMenu");
var icon = document.getElementById("menuIcon").querySelector("path");
function setOpen(open) {
menu.classList.toggle("hidden", !open);
button.setAttribute("aria-expanded", String(open));
button.setAttribute("aria-label", open ? "Close menu" : "Menu");
icon.setAttribute("d", open ? CROSS : BARS);
}
button.addEventListener("click", function () {
setOpen(menu.classList.contains("hidden"));
});
// Tapping a destination should close the sheet behind it.
menu.addEventListener("click", function (e) {
if (e.target.closest("a")) setOpen(false);
});
document.addEventListener("keydown", function (e) {
if (e.key === "Escape") setOpen(false);
});
// The panel is md:hidden, so a resize past the breakpoint hides it visually
// while aria-expanded would still claim it is open.
matchMedia("(min-width: 768px)").addEventListener("change", function (e) {
if (e.matches) setOpen(false);
});