08 / 24
All 24 in 24 Tailwind Liquid Glass Navbars
- 01Tailwind iOS 26 Floating Tab Bar
- 02Tailwind macOS Tahoe Menu Bar
- 03Tailwind Safari Toolbar with SVG Refraction
- 04Tailwind visionOS Glass Navbar
- 05Tailwind Liquid Glass Bottom Accessory Bar
- 06Tailwind Dynamic Island Morphing Nav
- 07Tailwind Liquid Glass Navbar (Canonical)
- 08Tailwind Responsive Glass Navbar with Burger
- 09Tailwind Next.js Sticky Glass Header
- 10Tailwind Spring Glide Menu (Framer Motion Port)
- 11Tailwind CSS Variables Glass Theme Generator
- 12Tailwind Glass Override for Bootstrap 5 Navbars
- 13Tailwind Scroll-Opacity Sticky Navbar
- 14Tailwind Inner-Glow Glass Nav Links
- 15Tailwind Cursor-Lens Glass Nav (GSAP-ready)
- 16Tailwind Animated Gradient Blobs Glass Navbar
- 17Tailwind Sliding Capsule Tab Bar (group-has)
- 18Tailwind Reflective Glass Sidebar
- 19Tailwind Fallback-First Glass Navbar
- 20Tailwind High-Contrast Accessible Glass Navbar
- 21Tailwind Light / Dark Liquid Glass Navbar
- 22Tailwind Performance-Tuned Glass Navbar
- 23Tailwind Minimalist Dual-Border Glass Header
- 24Tailwind Responsive Glass Sidebar to Bottom Tabs
Tailwind Responsive Glass Navbar with Burger
A glass navbar that collapses behind an animated burger — ported so the container query lives on the elements that respond to it (@max-[560px]:hidden) and the open state lives on one data-open attribute. That pairing is exactly what a React component wants: useState writes the attribute, and every visual consequence is already in the JSX class strings.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="nbtw-08 group relative block w-full min-h-svh overflow-hidden font-nb08-sans bg-[linear-gradient(130deg,#1fa2ff,#12d8fa_50%,#a6ffcb)]" id="nbtw-08-root" data-open="false" aria-label="Responsive glass navbar with burger demo">
<header class="@container relative z-[6] flex items-center gap-4 mx-auto mt-4 max-w-130 px-4 py-3 rounded-[18px] text-[#0a2540] bg-white/[0.24] border border-white/50 shadow-[inset_0_1px_0_rgba(255,255,255,.7),0_16px_36px_-20px_rgba(0,0,0,.4)] backdrop-blur-[20px] backdrop-saturate-[1.8]">
<a class="text-[17px] font-extrabold no-underline text-[#0a2540] focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">⬡ Stateful</a>
<nav class="flex gap-1 ms-auto @max-[560px]:hidden" aria-label="Primary">
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2 aria-[current=page]:bg-white/60" href="#nbtw-08" aria-current="page">Home</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Features</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Team</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Contact</a>
</nav>
<button class="hidden ms-auto size-11 flex-col items-center justify-center gap-[5px] border-0 bg-transparent cursor-pointer @max-[560px]:flex focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" id="nbtw-08-burger" type="button" aria-expanded="false" aria-controls="nbtw-08-sheet" aria-label="Menu">
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:translate-y-[7px] group-data-[open=true]:rotate-45 motion-reduce:transition-none"></span>
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:opacity-0 motion-reduce:transition-none"></span>
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:-translate-y-[7px] group-data-[open=true]:-rotate-45 motion-reduce:transition-none"></span>
</button>
</header>
<div class="absolute z-[5] left-1/2 top-[86px] -translate-x-1/2 -translate-y-2.5 w-[calc(100%-32px)] max-w-130 flex flex-col gap-1 p-2.5 rounded-[18px] bg-white/[0.28] border border-white/50 shadow-[0_24px_50px_-24px_rgba(0,0,0,.5)] backdrop-blur-[22px] backdrop-saturate-[1.8] opacity-0 invisible pointer-events-none transition-[opacity,transform,visibility] duration-300 group-data-[open=true]:opacity-100 group-data-[open=true]:visible group-data-[open=true]:pointer-events-auto group-data-[open=true]:translate-y-0 motion-reduce:transition-none" id="nbtw-08-sheet" role="group" aria-label="Mobile menu">
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2 aria-[current=page]:bg-white/60" href="#nbtw-08" aria-current="page">Home</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Features</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Team</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Contact</a>
</div>
<div class="grid place-items-center min-h-[60svh] px-6">
<p class="max-w-[38ch] text-center text-[#0a2540] text-[15px] font-semibold leading-[1.6]">Narrow the preview below 560px: the links hide and the burger appears, both stated as <code>@max-[560px]:</code> utilities on the elements themselves.</p>
</div>
</section><section class="nbtw-08 group relative block w-full min-h-svh overflow-hidden font-nb08-sans bg-[linear-gradient(130deg,#1fa2ff,#12d8fa_50%,#a6ffcb)]" id="nbtw-08-root" data-open="false" aria-label="Responsive glass navbar with burger demo">
<header class="@container relative z-[6] flex items-center gap-4 mx-auto mt-4 max-w-130 px-4 py-3 rounded-[18px] text-[#0a2540] bg-white/[0.24] border border-white/50 shadow-[inset_0_1px_0_rgba(255,255,255,.7),0_16px_36px_-20px_rgba(0,0,0,.4)] backdrop-blur-[20px] backdrop-saturate-[1.8]">
<a class="text-[17px] font-extrabold no-underline text-[#0a2540] focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">⬡ Stateful</a>
<nav class="flex gap-1 ms-auto @max-[560px]:hidden" aria-label="Primary">
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2 aria-[current=page]:bg-white/60" href="#nbtw-08" aria-current="page">Home</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Features</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Team</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Contact</a>
</nav>
<button class="hidden ms-auto size-11 flex-col items-center justify-center gap-[5px] border-0 bg-transparent cursor-pointer @max-[560px]:flex focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" id="nbtw-08-burger" type="button" aria-expanded="false" aria-controls="nbtw-08-sheet" aria-label="Menu">
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:translate-y-[7px] group-data-[open=true]:rotate-45 motion-reduce:transition-none"></span>
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:opacity-0 motion-reduce:transition-none"></span>
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:-translate-y-[7px] group-data-[open=true]:-rotate-45 motion-reduce:transition-none"></span>
</button>
</header>
<div class="absolute z-[5] left-1/2 top-[86px] -translate-x-1/2 -translate-y-2.5 w-[calc(100%-32px)] max-w-130 flex flex-col gap-1 p-2.5 rounded-[18px] bg-white/[0.28] border border-white/50 shadow-[0_24px_50px_-24px_rgba(0,0,0,.5)] backdrop-blur-[22px] backdrop-saturate-[1.8] opacity-0 invisible pointer-events-none transition-[opacity,transform,visibility] duration-300 group-data-[open=true]:opacity-100 group-data-[open=true]:visible group-data-[open=true]:pointer-events-auto group-data-[open=true]:translate-y-0 motion-reduce:transition-none" id="nbtw-08-sheet" role="group" aria-label="Mobile menu">
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2 aria-[current=page]:bg-white/60" href="#nbtw-08" aria-current="page">Home</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Features</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Team</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Contact</a>
</div>
<div class="grid place-items-center min-h-[60svh] px-6">
<p class="max-w-[38ch] text-center text-[#0a2540] text-[15px] font-semibold leading-[1.6]">Narrow the preview below 560px: the links hide and the burger appears, both stated as <code>@max-[560px]:</code> utilities on the elements themselves.</p>
</div>
</section>@import "tailwindcss";
@theme {
--font-nb08-sans: system-ui, 'Segoe UI', sans-serif;
}@import "tailwindcss";
@theme {
--font-nb08-sans: system-ui, 'Segoe UI', sans-serif;
}(() => {
const root = document.querySelector('#nbtw-08-root');
const burger = document.querySelector('#nbtw-08-burger');
const sheet = document.querySelector('#nbtw-08-sheet');
if (!root || !burger || !sheet) return;
let open = false; // React: const [open, setOpen] = useState(false)
const render = () => {
root.dataset.open = String(open); // React: data-open={String(open)}
burger.setAttribute('aria-expanded', String(open));
if (open) sheet.querySelector('a').focus();
};
burger.addEventListener('click', () => { open = !open; render(); });
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && open) { open = false; render(); burger.focus(); }
});
root.addEventListener('click', (e) => {
if (open && !e.target.closest('header') && !e.target.closest('#nbtw-08-sheet')) { open = false; render(); }
});
})();(() => {
const root = document.querySelector('#nbtw-08-root');
const burger = document.querySelector('#nbtw-08-burger');
const sheet = document.querySelector('#nbtw-08-sheet');
if (!root || !burger || !sheet) return;
let open = false; // React: const [open, setOpen] = useState(false)
const render = () => {
root.dataset.open = String(open); // React: data-open={String(open)}
burger.setAttribute('aria-expanded', String(open));
if (open) sheet.querySelector('a').focus();
};
burger.addEventListener('click', () => { open = !open; render(); });
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && open) { open = false; render(); burger.focus(); }
});
root.addEventListener('click', (e) => {
if (open && !e.target.closest('header') && !e.target.closest('#nbtw-08-sheet')) { open = false; render(); }
});
})();Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--font-nb08-sans: system-ui, 'Segoe UI', sans-serif;
}@import "tailwindcss";
@theme {
--font-nb08-sans: system-ui, 'Segoe UI', sans-serif;
}What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The container query is stated on the elements that respond to it.
@containeron the bar,@max-[560px]:hiddenon the links,@max-[560px]:flexon the burger — no reflow block at the bottom of a stylesheet to keep in your head. - The burger morph is three utilities per bar and no keyframes: translate plus rotate on the outer bars, opacity on the middle one, all driven by the root's
data-open. invisibleis in the class list andvisibilityis in the transition list, because anopacity-0sheet is still focusable — the bug this pattern is famous for.- The script is React-shaped on purpose: one boolean, one attribute write, ARIA in sync. In JSX it becomes
data-open={String(open)}with the identical class strings. grouplives on the root section, not the bar, because both the sheet and the burger bars need to read the same state from different subtrees.- Outside-click and Escape are handled in the vanilla version so the port to React does not quietly lose them.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Responsive Glass Navbar with Burger
Source: https://codefronts.com/navigation/tailwind-liquid-glass-navbars/tailwind-responsive-glass-navbar-with-burger/
A glass navbar that collapses behind an animated burger — ported so the container query lives on the elements that respond to it (@max-[560px]:hidden) and the open state lives on one data-open attribute. That pairing is exactly what a React component wants: useState writes the attribute, and every visual consequence is already in the JSX class strings.
## HTML
```html
<section class="nbtw-08 group relative block w-full min-h-svh overflow-hidden font-nb08-sans bg-[linear-gradient(130deg,#1fa2ff,#12d8fa_50%,#a6ffcb)]" id="nbtw-08-root" data-open="false" aria-label="Responsive glass navbar with burger demo">
<header class="@container relative z-[6] flex items-center gap-4 mx-auto mt-4 max-w-130 px-4 py-3 rounded-[18px] text-[#0a2540] bg-white/[0.24] border border-white/50 shadow-[inset_0_1px_0_rgba(255,255,255,.7),0_16px_36px_-20px_rgba(0,0,0,.4)] backdrop-blur-[20px] backdrop-saturate-[1.8]">
<a class="text-[17px] font-extrabold no-underline text-[#0a2540] focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">⬡ Stateful</a>
<nav class="flex gap-1 ms-auto @max-[560px]:hidden" aria-label="Primary">
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2 aria-[current=page]:bg-white/60" href="#nbtw-08" aria-current="page">Home</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Features</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Team</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Contact</a>
</nav>
<button class="hidden ms-auto size-11 flex-col items-center justify-center gap-[5px] border-0 bg-transparent cursor-pointer @max-[560px]:flex focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" id="nbtw-08-burger" type="button" aria-expanded="false" aria-controls="nbtw-08-sheet" aria-label="Menu">
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:translate-y-[7px] group-data-[open=true]:rotate-45 motion-reduce:transition-none"></span>
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:opacity-0 motion-reduce:transition-none"></span>
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:-translate-y-[7px] group-data-[open=true]:-rotate-45 motion-reduce:transition-none"></span>
</button>
</header>
<div class="absolute z-[5] left-1/2 top-[86px] -translate-x-1/2 -translate-y-2.5 w-[calc(100%-32px)] max-w-130 flex flex-col gap-1 p-2.5 rounded-[18px] bg-white/[0.28] border border-white/50 shadow-[0_24px_50px_-24px_rgba(0,0,0,.5)] backdrop-blur-[22px] backdrop-saturate-[1.8] opacity-0 invisible pointer-events-none transition-[opacity,transform,visibility] duration-300 group-data-[open=true]:opacity-100 group-data-[open=true]:visible group-data-[open=true]:pointer-events-auto group-data-[open=true]:translate-y-0 motion-reduce:transition-none" id="nbtw-08-sheet" role="group" aria-label="Mobile menu">
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2 aria-[current=page]:bg-white/60" href="#nbtw-08" aria-current="page">Home</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Features</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Team</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Contact</a>
</div>
<div class="grid place-items-center min-h-[60svh] px-6">
<p class="max-w-[38ch] text-center text-[#0a2540] text-[15px] font-semibold leading-[1.6]">Narrow the preview below 560px: the links hide and the burger appears, both stated as <code>@max-[560px]:</code> utilities on the elements themselves.</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--font-nb08-sans: system-ui, 'Segoe UI', sans-serif;
}
```
## JavaScript
```js
(() => {
const root = document.querySelector('#nbtw-08-root');
const burger = document.querySelector('#nbtw-08-burger');
const sheet = document.querySelector('#nbtw-08-sheet');
if (!root || !burger || !sheet) return;
let open = false; // React: const [open, setOpen] = useState(false)
const render = () => {
root.dataset.open = String(open); // React: data-open={String(open)}
burger.setAttribute('aria-expanded', String(open));
if (open) sheet.querySelector('a').focus();
};
burger.addEventListener('click', () => { open = !open; render(); });
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && open) { open = false; render(); burger.focus(); }
});
root.addEventListener('click', (e) => {
if (open && !e.target.closest('header') && !e.target.closest('#nbtw-08-sheet')) { open = false; render(); }
});
})();
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Responsive Glass Navbar with Burger
Source: https://codefronts.com/navigation/tailwind-liquid-glass-navbars/tailwind-responsive-glass-navbar-with-burger/
A glass navbar that collapses behind an animated burger — ported so the container query lives on the elements that respond to it (@max-[560px]:hidden) and the open state lives on one data-open attribute. That pairing is exactly what a React component wants: useState writes the attribute, and every visual consequence is already in the JSX class strings.
## HTML
```html
<section class="nbtw-08 group relative block w-full min-h-svh overflow-hidden font-nb08-sans bg-[linear-gradient(130deg,#1fa2ff,#12d8fa_50%,#a6ffcb)]" id="nbtw-08-root" data-open="false" aria-label="Responsive glass navbar with burger demo">
<header class="@container relative z-[6] flex items-center gap-4 mx-auto mt-4 max-w-130 px-4 py-3 rounded-[18px] text-[#0a2540] bg-white/[0.24] border border-white/50 shadow-[inset_0_1px_0_rgba(255,255,255,.7),0_16px_36px_-20px_rgba(0,0,0,.4)] backdrop-blur-[20px] backdrop-saturate-[1.8]">
<a class="text-[17px] font-extrabold no-underline text-[#0a2540] focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">⬡ Stateful</a>
<nav class="flex gap-1 ms-auto @max-[560px]:hidden" aria-label="Primary">
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2 aria-[current=page]:bg-white/60" href="#nbtw-08" aria-current="page">Home</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Features</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Team</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-[#0a2540] text-[14.5px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Contact</a>
</nav>
<button class="hidden ms-auto size-11 flex-col items-center justify-center gap-[5px] border-0 bg-transparent cursor-pointer @max-[560px]:flex focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" id="nbtw-08-burger" type="button" aria-expanded="false" aria-controls="nbtw-08-sheet" aria-label="Menu">
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:translate-y-[7px] group-data-[open=true]:rotate-45 motion-reduce:transition-none"></span>
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:opacity-0 motion-reduce:transition-none"></span>
<span class="w-5.5 h-0.5 rounded-sm bg-[#0a2540] transition-[transform,opacity] duration-300 group-data-[open=true]:-translate-y-[7px] group-data-[open=true]:-rotate-45 motion-reduce:transition-none"></span>
</button>
</header>
<div class="absolute z-[5] left-1/2 top-[86px] -translate-x-1/2 -translate-y-2.5 w-[calc(100%-32px)] max-w-130 flex flex-col gap-1 p-2.5 rounded-[18px] bg-white/[0.28] border border-white/50 shadow-[0_24px_50px_-24px_rgba(0,0,0,.5)] backdrop-blur-[22px] backdrop-saturate-[1.8] opacity-0 invisible pointer-events-none transition-[opacity,transform,visibility] duration-300 group-data-[open=true]:opacity-100 group-data-[open=true]:visible group-data-[open=true]:pointer-events-auto group-data-[open=true]:translate-y-0 motion-reduce:transition-none" id="nbtw-08-sheet" role="group" aria-label="Mobile menu">
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2 aria-[current=page]:bg-white/60" href="#nbtw-08" aria-current="page">Home</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Features</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Team</a>
<a class="flex items-center min-h-11 px-3.5 rounded-xl no-underline text-[#0a2540] text-[15px] font-semibold transition-colors duration-200 hover:bg-white/45 focus-visible:outline-2 focus-visible:outline-[#0a2540] focus-visible:outline-offset-2" href="#nbtw-08">Contact</a>
</div>
<div class="grid place-items-center min-h-[60svh] px-6">
<p class="max-w-[38ch] text-center text-[#0a2540] text-[15px] font-semibold leading-[1.6]">Narrow the preview below 560px: the links hide and the burger appears, both stated as <code>@max-[560px]:</code> utilities on the elements themselves.</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--font-nb08-sans: system-ui, 'Segoe UI', sans-serif;
}
```
## JavaScript
```js
(() => {
const root = document.querySelector('#nbtw-08-root');
const burger = document.querySelector('#nbtw-08-burger');
const sheet = document.querySelector('#nbtw-08-sheet');
if (!root || !burger || !sheet) return;
let open = false; // React: const [open, setOpen] = useState(false)
const render = () => {
root.dataset.open = String(open); // React: data-open={String(open)}
burger.setAttribute('aria-expanded', String(open));
if (open) sheet.querySelector('a').focus();
};
burger.addEventListener('click', () => { open = !open; render(); });
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && open) { open = false; render(); burger.focus(); }
});
root.addEventListener('click', (e) => {
if (open && !e.target.closest('header') && !e.target.closest('#nbtw-08-sheet')) { open = false; render(); }
});
})();
```How this works
The container query moves into the markup. The bar declares itself a container; the links and the burger each state what they do below the breakpoint:
<header class="@container ...">
<nav class="flex @max-[560px]:hidden">…</nav>
<button class="hidden @max-[560px]:flex ...">…</button>This is a genuine readability win over the CSS version: the reflow rule is no longer a block at the bottom of the stylesheet that you have to hold in your head while reading the markup.
One attribute drives the sheet and the burger. The root carries group and data-open; the sheet fades and slides, and the three burger bars form an X, all from group-data-[open=true]: variants. The script never touches a class:
let open = false; // React: const [open, setOpen] = useState(false)
root.dataset.open = String(open); // React: data-open={String(open)}Closed means closed. The sheet pairs opacity-0 pointer-events-none invisible at rest with the visible trio when open, so a keyboard user cannot tab into an invisible menu — the failure mode that opacity alone always leaves behind.
Porting to React is a copy-paste. Because the state is an attribute and the design is variants of it, the JSX is the same markup with data-open={String(open)} and onClick={() => setOpen(!open)}. No class-name string juggling, no clsx.
Make it yours
- Change the breakpoint by editing
@max-[560px]on the three elements that use it, or switch to a named container size (@max-md:) if it matches your scale. - Swap the sheet's entrance by changing the resting transform:
scale-95toscale-100reads snappier than a slide. - Port to React by rendering
data-openfrom state; every utility in the markup keeps working untouched. - Add a scrim by placing a sibling
fixed inset-0 bg-black/30with the samegroup-data-[open=true]:pair. - Keep the links visible at all widths by deleting the two
@max-[560px]:utilities on the nav and burger.
Gotchas — read before shipping
- Container query variants need an ancestor with
@container. Without it@max-[560px]:compiles but never matches. - Move focus into the sheet on open and back to the burger on close — the script does both, and skipping it is the most common accessibility regression in this pattern.
opacity-0alone leaves a closed sheet focusable. Pair it withinvisibleandpointer-events-none, and putvisibilityin the transition list so it does not snap.- Lock body scroll while the sheet is open on a real mobile page; a floating glass sheet over a scrolling body feels broken.
- Keep the burger a 44px button (
size-11), not a bare icon — the three bars inside are decorative spans. group-data-*on the burger bars resolves against the root'sgroup, so do not add a second unnamedgroupon the bar; use a named group if you need both.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Tailwind v4 sets the floor, and container queries are inside it (Chrome 105+, Safari 16+, Firefox 110+). The open state is JS; without it the sheet stays closed and the inline links remain the whole navigation above the breakpoint.