24 / 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 Sidebar to Bottom Tabs
One glass navigation that adapts to its container: a floating vertical sidebar when there is room, re-flowing into a bottom tab bar when there is not. Same links, same material, no duplicated markup and no JavaScript. The port puts the whole reflow on the elements as @max-[560px]: utilities, which makes the two layouts readable side by side.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="nbtw-24 w-full min-h-svh p-3.5 font-nb24-sans bg-[linear-gradient(130deg,#654ea3,#4776e6_60%,#8e54e9)]" aria-label="Responsive glass sidebar to bottom tabs demo">
<div class="@container relative min-h-[calc(100svh-28px)] rounded-[20px] overflow-hidden bg-[radial-gradient(circle_at_30%_20%,rgba(255,255,255,.14),transparent_60%),url('https://picsum.photos/seed/nb24/1000/700')] bg-center bg-cover">
<nav class="absolute z-[5] top-4 left-4 bottom-4 flex flex-col items-stretch gap-1.5 w-[150px] px-2.5 py-3.5 rounded-[18px] text-white bg-[color-mix(in_oklab,white_14%,transparent)] border border-white/40 shadow-[inset_0_1px_0_rgba(255,255,255,.5),0_20px_44px_-24px_rgba(0,0,0,.6)] backdrop-blur-[24px] backdrop-saturate-[1.8] @max-[560px]:top-auto @max-[560px]:inset-x-4 @max-[560px]:bottom-4 @max-[560px]:w-auto @max-[560px]:flex-row @max-[560px]:justify-around @max-[560px]:p-2" aria-label="Primary">
<span class="py-1.5 pb-2.5 text-center text-[22px] @max-[560px]:hidden" aria-hidden="true">◆</span>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 aria-[current=page]:bg-white/[0.24] aria-[current=page]:text-white @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24" aria-current="page"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">⌂</span><span class="@max-[560px]:text-[11px]">Home</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">⌕</span><span class="@max-[560px]:text-[11px]">Search</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">▤</span><span class="@max-[560px]:text-[11px]">Library</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">◔</span><span class="@max-[560px]:text-[11px]">Activity</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">◉</span><span class="@max-[560px]:text-[11px]">Profile</span></a>
</nav>
<div class="min-h-[calc(100svh-28px)] grid place-items-center p-6 ps-[190px] @max-[560px]:p-6 @max-[560px]:pb-30">
<p class="max-w-[34ch] text-center text-white text-[15px] font-semibold leading-[1.6] [text-shadow:0_2px_14px_rgba(0,0,0,.35)]">Resize the preview: the glass sidebar re-flows into a bottom tab bar — one nav, one material, zero duplicate markup, and the whole reflow stated on the elements themselves.</p>
</div>
</div>
</section><section class="nbtw-24 w-full min-h-svh p-3.5 font-nb24-sans bg-[linear-gradient(130deg,#654ea3,#4776e6_60%,#8e54e9)]" aria-label="Responsive glass sidebar to bottom tabs demo">
<div class="@container relative min-h-[calc(100svh-28px)] rounded-[20px] overflow-hidden bg-[radial-gradient(circle_at_30%_20%,rgba(255,255,255,.14),transparent_60%),url('https://picsum.photos/seed/nb24/1000/700')] bg-center bg-cover">
<nav class="absolute z-[5] top-4 left-4 bottom-4 flex flex-col items-stretch gap-1.5 w-[150px] px-2.5 py-3.5 rounded-[18px] text-white bg-[color-mix(in_oklab,white_14%,transparent)] border border-white/40 shadow-[inset_0_1px_0_rgba(255,255,255,.5),0_20px_44px_-24px_rgba(0,0,0,.6)] backdrop-blur-[24px] backdrop-saturate-[1.8] @max-[560px]:top-auto @max-[560px]:inset-x-4 @max-[560px]:bottom-4 @max-[560px]:w-auto @max-[560px]:flex-row @max-[560px]:justify-around @max-[560px]:p-2" aria-label="Primary">
<span class="py-1.5 pb-2.5 text-center text-[22px] @max-[560px]:hidden" aria-hidden="true">◆</span>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 aria-[current=page]:bg-white/[0.24] aria-[current=page]:text-white @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24" aria-current="page"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">⌂</span><span class="@max-[560px]:text-[11px]">Home</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">⌕</span><span class="@max-[560px]:text-[11px]">Search</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">▤</span><span class="@max-[560px]:text-[11px]">Library</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">◔</span><span class="@max-[560px]:text-[11px]">Activity</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">◉</span><span class="@max-[560px]:text-[11px]">Profile</span></a>
</nav>
<div class="min-h-[calc(100svh-28px)] grid place-items-center p-6 ps-[190px] @max-[560px]:p-6 @max-[560px]:pb-30">
<p class="max-w-[34ch] text-center text-white text-[15px] font-semibold leading-[1.6] [text-shadow:0_2px_14px_rgba(0,0,0,.35)]">Resize the preview: the glass sidebar re-flows into a bottom tab bar — one nav, one material, zero duplicate markup, and the whole reflow stated on the elements themselves.</p>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--font-nb24-sans: system-ui, 'Segoe UI', sans-serif;
}@import "tailwindcss";
@theme {
--font-nb24-sans: system-ui, 'Segoe UI', sans-serif;
}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-nb24-sans: system-ui, 'Segoe UI', sans-serif;
}@import "tailwindcss";
@theme {
--font-nb24-sans: system-ui, 'Segoe UI', sans-serif;
}What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Both layouts live in one class list, which is the readability argument for container-query variants: you can see the sidebar and the tab bar described side by side.
- The query is against the app shell's inline size, not the viewport, so the nav reflows correctly inside a split pane or an embedded preview — the cases a media query gets wrong.
- Only layout properties change. The glass recipe is written once and shared by both forms, which is what keeps them reading as one component.
- There is exactly one copy of the links. No mobile duplicate to drift, and no second set of accessible names to maintain.
- 44px targets are preserved in both directions —
min-h-11for the sidebar rows,min-w-14for the bottom tabs. - The main region flips its own padding under the same variant, because content hiding behind a bottom bar is the classic bug in this pattern.
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 Sidebar to Bottom Tabs
Source: https://codefronts.com/navigation/tailwind-liquid-glass-navbars/tailwind-responsive-glass-sidebar-to-bottom-tabs/
One glass navigation that adapts to its container: a floating vertical sidebar when there is room, re-flowing into a bottom tab bar when there is not. Same links, same material, no duplicated markup and no JavaScript. The port puts the whole reflow on the elements as @max-[560px]: utilities, which makes the two layouts readable side by side.
## HTML
```html
<section class="nbtw-24 w-full min-h-svh p-3.5 font-nb24-sans bg-[linear-gradient(130deg,#654ea3,#4776e6_60%,#8e54e9)]" aria-label="Responsive glass sidebar to bottom tabs demo">
<div class="@container relative min-h-[calc(100svh-28px)] rounded-[20px] overflow-hidden bg-[radial-gradient(circle_at_30%_20%,rgba(255,255,255,.14),transparent_60%),url('https://picsum.photos/seed/nb24/1000/700')] bg-center bg-cover">
<nav class="absolute z-[5] top-4 left-4 bottom-4 flex flex-col items-stretch gap-1.5 w-[150px] px-2.5 py-3.5 rounded-[18px] text-white bg-[color-mix(in_oklab,white_14%,transparent)] border border-white/40 shadow-[inset_0_1px_0_rgba(255,255,255,.5),0_20px_44px_-24px_rgba(0,0,0,.6)] backdrop-blur-[24px] backdrop-saturate-[1.8] @max-[560px]:top-auto @max-[560px]:inset-x-4 @max-[560px]:bottom-4 @max-[560px]:w-auto @max-[560px]:flex-row @max-[560px]:justify-around @max-[560px]:p-2" aria-label="Primary">
<span class="py-1.5 pb-2.5 text-center text-[22px] @max-[560px]:hidden" aria-hidden="true">◆</span>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 aria-[current=page]:bg-white/[0.24] aria-[current=page]:text-white @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24" aria-current="page"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">⌂</span><span class="@max-[560px]:text-[11px]">Home</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">⌕</span><span class="@max-[560px]:text-[11px]">Search</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">▤</span><span class="@max-[560px]:text-[11px]">Library</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">◔</span><span class="@max-[560px]:text-[11px]">Activity</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">◉</span><span class="@max-[560px]:text-[11px]">Profile</span></a>
</nav>
<div class="min-h-[calc(100svh-28px)] grid place-items-center p-6 ps-[190px] @max-[560px]:p-6 @max-[560px]:pb-30">
<p class="max-w-[34ch] text-center text-white text-[15px] font-semibold leading-[1.6] [text-shadow:0_2px_14px_rgba(0,0,0,.35)]">Resize the preview: the glass sidebar re-flows into a bottom tab bar — one nav, one material, zero duplicate markup, and the whole reflow stated on the elements themselves.</p>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--font-nb24-sans: system-ui, 'Segoe UI', sans-serif;
}
```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 Sidebar to Bottom Tabs
Source: https://codefronts.com/navigation/tailwind-liquid-glass-navbars/tailwind-responsive-glass-sidebar-to-bottom-tabs/
One glass navigation that adapts to its container: a floating vertical sidebar when there is room, re-flowing into a bottom tab bar when there is not. Same links, same material, no duplicated markup and no JavaScript. The port puts the whole reflow on the elements as @max-[560px]: utilities, which makes the two layouts readable side by side.
## HTML
```html
<section class="nbtw-24 w-full min-h-svh p-3.5 font-nb24-sans bg-[linear-gradient(130deg,#654ea3,#4776e6_60%,#8e54e9)]" aria-label="Responsive glass sidebar to bottom tabs demo">
<div class="@container relative min-h-[calc(100svh-28px)] rounded-[20px] overflow-hidden bg-[radial-gradient(circle_at_30%_20%,rgba(255,255,255,.14),transparent_60%),url('https://picsum.photos/seed/nb24/1000/700')] bg-center bg-cover">
<nav class="absolute z-[5] top-4 left-4 bottom-4 flex flex-col items-stretch gap-1.5 w-[150px] px-2.5 py-3.5 rounded-[18px] text-white bg-[color-mix(in_oklab,white_14%,transparent)] border border-white/40 shadow-[inset_0_1px_0_rgba(255,255,255,.5),0_20px_44px_-24px_rgba(0,0,0,.6)] backdrop-blur-[24px] backdrop-saturate-[1.8] @max-[560px]:top-auto @max-[560px]:inset-x-4 @max-[560px]:bottom-4 @max-[560px]:w-auto @max-[560px]:flex-row @max-[560px]:justify-around @max-[560px]:p-2" aria-label="Primary">
<span class="py-1.5 pb-2.5 text-center text-[22px] @max-[560px]:hidden" aria-hidden="true">◆</span>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 aria-[current=page]:bg-white/[0.24] aria-[current=page]:text-white @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24" aria-current="page"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">⌂</span><span class="@max-[560px]:text-[11px]">Home</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">⌕</span><span class="@max-[560px]:text-[11px]">Search</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">▤</span><span class="@max-[560px]:text-[11px]">Library</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">◔</span><span class="@max-[560px]:text-[11px]">Activity</span></a>
<a class="flex items-center gap-3 min-h-11 px-3.5 rounded-xl no-underline text-white/85 text-[14.5px] font-semibold transition-[background-color,color] duration-200 hover:bg-white/[0.16] hover:text-white focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 @max-[560px]:flex-col @max-[560px]:gap-[3px] @max-[560px]:justify-center @max-[560px]:min-w-14 @max-[560px]:px-1.5 @max-[560px]:py-1.5" href="#nbtw-24"><span class="w-5.5 text-center text-[19px] leading-none @max-[560px]:w-auto" aria-hidden="true">◉</span><span class="@max-[560px]:text-[11px]">Profile</span></a>
</nav>
<div class="min-h-[calc(100svh-28px)] grid place-items-center p-6 ps-[190px] @max-[560px]:p-6 @max-[560px]:pb-30">
<p class="max-w-[34ch] text-center text-white text-[15px] font-semibold leading-[1.6] [text-shadow:0_2px_14px_rgba(0,0,0,.35)]">Resize the preview: the glass sidebar re-flows into a bottom tab bar — one nav, one material, zero duplicate markup, and the whole reflow stated on the elements themselves.</p>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--font-nb24-sans: system-ui, 'Segoe UI', sans-serif;
}
```How this works
The nav is one element with two layouts. Both are legible in the same class list, which is the readability argument for container-query variants in one sentence:
class="absolute top-4 left-4 bottom-4 w-[150px] flex flex-col
@max-[560px]:top-auto @max-[560px]:inset-x-4 @max-[560px]:bottom-4
@max-[560px]:w-auto @max-[560px]:flex-row @max-[560px]:justify-around"Container, not viewport. The query is against the app shell's inline size, so this nav reflows correctly in a split pane, an embedded preview, or a dashboard column — every place a viewport media query gets the answer wrong.
Only layout changes. The fill, rim, shadow and blur are written once and inherited by both forms. That is what keeps the two states looking like one component at two shapes rather than two designs.
One source of truth for the links. There is no mobile copy of the navigation to fall out of sync — the single most valuable property of this pattern, and the reason it is worth the slightly denser class lists.
Make it yours
- Change the breakpoint by editing
@max-[560px]on the four elements that use it, or move to a named container size if it matches your scale. - Hide labels entirely in the bottom bar with
@max-[560px]:hiddenon the label span — keep thearia-labels if you do. - Anchor the sidebar to the right with
right-4 left-auto, or detach it further with a larger inset for a more floating look. - Add a second breakpoint (
@max-[380px]:) to drop to icons only on the narrowest containers. - Swap the container query for a media query if the nav is always at viewport scale; the utility names barely change.
Gotchas — read before shipping
- Container query variants need an ancestor with
@container. Without it every@max-[560px]:utility compiles and silently never matches. - The container must be a sized ancestor of the nav, not the nav itself — an element cannot query its own inline size.
- Keep 44px targets in both orientations. It is easy to satisfy the vertical form and end up with 32px-tall bottom tabs.
- Never duplicate the links for mobile. Two copies of a navigation is how the two versions drift, and it doubles the accessible-name maintenance.
- The main region needs its padding flipped too (
@max-[560px]:p-6), or content hides behind the bottom bar. - Container queries create a containment context, which can affect how absolutely-positioned descendants resolve. Check any overlay inside the shell after adding one.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Tailwind v4 sets the floor, and container queries (Chrome 105+, Safari 16+, Firefox 110+) are inside it. Where they are unavailable the nav keeps its sidebar layout, which remains fully usable.