22 / 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 Performance-Tuned Glass Navbar
The glass navbar built for a steady 60fps and clean Core Web Vitals: the expensive paint is boxed with [contain:layout_paint_style] and isolate, the compositor is hinted with will-change-transform on the one animating layer, the specular sweep animates transform only, and the blur is capped on purpose. The port keeps every one of those decisions visible on the element it applies to.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="nbtw-22 grid place-items-center w-full min-h-svh p-5 font-nb22-sans bg-[linear-gradient(120deg,#2c3e50,#4ca1af_70%,#c4e0e5)]" aria-label="Performance tuned glass navbar demo">
<nav class="relative overflow-hidden isolate [contain:layout_paint_style] flex flex-wrap items-center gap-x-4.5 gap-y-3 w-[min(740px,100%)] px-4.5 py-3.5 rounded-2xl text-white bg-[color-mix(in_oklab,white_12%,transparent)] border border-white/[0.34] shadow-[inset_0_1px_0_rgba(255,255,255,.5),0_16px_38px_-22px_rgba(0,0,0,.55)] backdrop-blur-[18px] backdrop-saturate-[1.7]" aria-label="Primary">
<span class="absolute inset-0 z-0 pointer-events-none -translate-x-[120%] will-change-transform bg-[linear-gradient(105deg,transparent_40%,rgba(255,255,255,.35)_50%,transparent_60%)] animate-nb22-sweep motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] text-base font-extrabold">⚡ Sixty</span>
<div class="relative z-[1] flex flex-wrap gap-1">
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 aria-[current=page]:opacity-100 aria-[current=page]:bg-white/[0.18]" href="#nbtw-22" aria-current="page">Home</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Metrics</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Budget</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Docs</a>
</div>
<span class="relative z-[1] ms-auto text-[11px] font-bold tracking-[0.06em] uppercase tabular-nums text-white/70" aria-hidden="true">60 fps</span>
</nav>
</section><section class="nbtw-22 grid place-items-center w-full min-h-svh p-5 font-nb22-sans bg-[linear-gradient(120deg,#2c3e50,#4ca1af_70%,#c4e0e5)]" aria-label="Performance tuned glass navbar demo">
<nav class="relative overflow-hidden isolate [contain:layout_paint_style] flex flex-wrap items-center gap-x-4.5 gap-y-3 w-[min(740px,100%)] px-4.5 py-3.5 rounded-2xl text-white bg-[color-mix(in_oklab,white_12%,transparent)] border border-white/[0.34] shadow-[inset_0_1px_0_rgba(255,255,255,.5),0_16px_38px_-22px_rgba(0,0,0,.55)] backdrop-blur-[18px] backdrop-saturate-[1.7]" aria-label="Primary">
<span class="absolute inset-0 z-0 pointer-events-none -translate-x-[120%] will-change-transform bg-[linear-gradient(105deg,transparent_40%,rgba(255,255,255,.35)_50%,transparent_60%)] animate-nb22-sweep motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] text-base font-extrabold">⚡ Sixty</span>
<div class="relative z-[1] flex flex-wrap gap-1">
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 aria-[current=page]:opacity-100 aria-[current=page]:bg-white/[0.18]" href="#nbtw-22" aria-current="page">Home</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Metrics</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Budget</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Docs</a>
</div>
<span class="relative z-[1] ms-auto text-[11px] font-bold tracking-[0.06em] uppercase tabular-nums text-white/70" aria-hidden="true">60 fps</span>
</nav>
</section>@import "tailwindcss";
@theme {
--font-nb22-sans: system-ui, 'Segoe UI', sans-serif;
--animate-nb22-sweep: nb22-sweep 5s ease-in-out infinite;
}
/* Transform only, with a long idle phase, so the specular pass stays on the
compositor and never touches layout or paint. */
@keyframes nb22-sweep {
0%,
60% {
transform: translateX(-120%);
}
100% {
transform: translateX(120%);
}
}@import "tailwindcss";
@theme {
--font-nb22-sans: system-ui, 'Segoe UI', sans-serif;
--animate-nb22-sweep: nb22-sweep 5s ease-in-out infinite;
}
/* Transform only, with a long idle phase, so the specular pass stays on the
compositor and never touches layout or paint. */
@keyframes nb22-sweep {
0%,
60% {
transform: translateX(-120%);
}
100% {
transform: translateX(120%);
}
}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-nb22-sans: system-ui, 'Segoe UI', sans-serif;
--animate-nb22-sweep: nb22-sweep 5s ease-in-out infinite;
}
/* Transform only, with a long idle phase, so the specular pass stays on the
compositor and never touches layout or paint. */
@keyframes nb22-sweep {
0%,
60% {
transform: translateX(-120%);
}
100% {
transform: translateX(120%);
}
}@import "tailwindcss";
@theme {
--font-nb22-sans: system-ui, 'Segoe UI', sans-serif;
--animate-nb22-sweep: nb22-sweep 5s ease-in-out infinite;
}
/* Transform only, with a long idle phase, so the specular pass stays on the
compositor and never touches layout or paint. */
@keyframes nb22-sweep {
0%,
60% {
transform: translateX(-120%);
}
100% {
transform: translateX(120%);
}
}What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Every performance decision is visible on the element it applies to: containment and isolation on the bar,
will-change-transformon the sweep and nowhere else, the blur cap as a greppable number. [contain:layout_paint_style]is an arbitrary property because containment is an engine hint, not a design token — and at these blur radii it is doing the heaviest lifting in the demo.will-change-transformappears exactly once. Spread across a navbar it reserves memory per layer and makes things slower, which is the misuse this entry exists to demonstrate against.- The sweep animates
translateXonly, from an--animate-*theme entry, so retiming is one token edit and the animation never leaves the compositor. motion-reduce:hiddenremoves the shimmer rather than slowing it — an ambient specular pass has no calm version worth keeping.- Containment establishes an independent formatting context, so absolutely-positioned children resolve against the bar. That is why the sweep and the links need no extra positioning parent.
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 Performance-Tuned Glass Navbar
Source: https://codefronts.com/navigation/tailwind-liquid-glass-navbars/tailwind-performance-tuned-glass-navbar/
The glass navbar built for a steady 60fps and clean Core Web Vitals: the expensive paint is boxed with [contain:layout_paint_style] and isolate, the compositor is hinted with will-change-transform on the one animating layer, the specular sweep animates transform only, and the blur is capped on purpose. The port keeps every one of those decisions visible on the element it applies to.
## HTML
```html
<section class="nbtw-22 grid place-items-center w-full min-h-svh p-5 font-nb22-sans bg-[linear-gradient(120deg,#2c3e50,#4ca1af_70%,#c4e0e5)]" aria-label="Performance tuned glass navbar demo">
<nav class="relative overflow-hidden isolate [contain:layout_paint_style] flex flex-wrap items-center gap-x-4.5 gap-y-3 w-[min(740px,100%)] px-4.5 py-3.5 rounded-2xl text-white bg-[color-mix(in_oklab,white_12%,transparent)] border border-white/[0.34] shadow-[inset_0_1px_0_rgba(255,255,255,.5),0_16px_38px_-22px_rgba(0,0,0,.55)] backdrop-blur-[18px] backdrop-saturate-[1.7]" aria-label="Primary">
<span class="absolute inset-0 z-0 pointer-events-none -translate-x-[120%] will-change-transform bg-[linear-gradient(105deg,transparent_40%,rgba(255,255,255,.35)_50%,transparent_60%)] animate-nb22-sweep motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] text-base font-extrabold">⚡ Sixty</span>
<div class="relative z-[1] flex flex-wrap gap-1">
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 aria-[current=page]:opacity-100 aria-[current=page]:bg-white/[0.18]" href="#nbtw-22" aria-current="page">Home</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Metrics</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Budget</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Docs</a>
</div>
<span class="relative z-[1] ms-auto text-[11px] font-bold tracking-[0.06em] uppercase tabular-nums text-white/70" aria-hidden="true">60 fps</span>
</nav>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--font-nb22-sans: system-ui, 'Segoe UI', sans-serif;
--animate-nb22-sweep: nb22-sweep 5s ease-in-out infinite;
}
/* Transform only, with a long idle phase, so the specular pass stays on the
compositor and never touches layout or paint. */
@keyframes nb22-sweep {
0%,
60% {
transform: translateX(-120%);
}
100% {
transform: translateX(120%);
}
}
```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 Performance-Tuned Glass Navbar
Source: https://codefronts.com/navigation/tailwind-liquid-glass-navbars/tailwind-performance-tuned-glass-navbar/
The glass navbar built for a steady 60fps and clean Core Web Vitals: the expensive paint is boxed with [contain:layout_paint_style] and isolate, the compositor is hinted with will-change-transform on the one animating layer, the specular sweep animates transform only, and the blur is capped on purpose. The port keeps every one of those decisions visible on the element it applies to.
## HTML
```html
<section class="nbtw-22 grid place-items-center w-full min-h-svh p-5 font-nb22-sans bg-[linear-gradient(120deg,#2c3e50,#4ca1af_70%,#c4e0e5)]" aria-label="Performance tuned glass navbar demo">
<nav class="relative overflow-hidden isolate [contain:layout_paint_style] flex flex-wrap items-center gap-x-4.5 gap-y-3 w-[min(740px,100%)] px-4.5 py-3.5 rounded-2xl text-white bg-[color-mix(in_oklab,white_12%,transparent)] border border-white/[0.34] shadow-[inset_0_1px_0_rgba(255,255,255,.5),0_16px_38px_-22px_rgba(0,0,0,.55)] backdrop-blur-[18px] backdrop-saturate-[1.7]" aria-label="Primary">
<span class="absolute inset-0 z-0 pointer-events-none -translate-x-[120%] will-change-transform bg-[linear-gradient(105deg,transparent_40%,rgba(255,255,255,.35)_50%,transparent_60%)] animate-nb22-sweep motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] text-base font-extrabold">⚡ Sixty</span>
<div class="relative z-[1] flex flex-wrap gap-1">
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 aria-[current=page]:opacity-100 aria-[current=page]:bg-white/[0.18]" href="#nbtw-22" aria-current="page">Home</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Metrics</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Budget</a>
<a class="flex items-center min-h-10 px-3.5 rounded-[10px] no-underline text-white opacity-90 text-[14.5px] font-semibold transition-[background-color,opacity] duration-200 hover:opacity-100 hover:bg-white/[0.18] focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2" href="#nbtw-22">Docs</a>
</div>
<span class="relative z-[1] ms-auto text-[11px] font-bold tracking-[0.06em] uppercase tabular-nums text-white/70" aria-hidden="true">60 fps</span>
</nav>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--font-nb22-sans: system-ui, 'Segoe UI', sans-serif;
--animate-nb22-sweep: nb22-sweep 5s ease-in-out infinite;
}
/* Transform only, with a long idle phase, so the specular pass stays on the
compositor and never touches layout or paint. */
@keyframes nb22-sweep {
0%,
60% {
transform: translateX(-120%);
}
100% {
transform: translateX(120%);
}
}
```How this works
Containment is the headline. A backdrop-filter samples what is behind it, which can pull the whole page into a repaint. Declaring containment tells the engine the damage is bounded:
class="relative overflow-hidden isolate [contain:layout_paint_style]
backdrop-blur-[18px] backdrop-saturate-[1.7]"The sweep is compositor-only. One keyframe pair moving a gradient layer with translateX — no width, no left, no opacity on a large surface. Its animation is a theme entry, so retiming happens in one place:
--animate-nb22-sweep: nb22-sweep 5s ease-in-out infinite;
@keyframes nb22-sweep { 0%,60% { transform: translateX(-120%) } 100% { transform: translateX(120%) } }will-change is a scalpel. It promotes the sweep to its own layer, and it appears exactly once. Applied to the bar or the links it would cost memory permanently for no gain — the classic misuse this demo is written to avoid.
The blur cap is a design decision. 18px is chosen against a device budget rather than aesthetics. Because it is a bracket value on the element, it is greppable: you can find every capped blur in a codebase and raise or lower the budget deliberately.
Make it yours
- Raise or lower the blur cap to match your device budget; treat 24px as the ceiling on mid-tier mobile.
- Retime the sweep in
@theme, or lengthen its idle phase by moving the60%keyframe stop. - Add
content-visibility:autoto long offscreen content below the bar for extra savings; it pairs well with containment here. - Drop the sweep entirely for the cheapest possible glass bar — nothing else in the demo animates.
- Toggle
will-changejust-in-time from JavaScript around interactions if you need it on more than one layer.
Gotchas — read before shipping
- Never leave
will-changeon permanently across many elements. It reserves memory per layer, and a navbar full of promoted layers is slower, not faster. - Do not animate blur radius. Animate the transform or opacity of an already-blurred layer, which is what the sweep does.
contain: strictclips outer shadows.layout paint styleis the combination that keeps the ambient shadow while still bounding the paint.- Containment changes layout semantics: a contained element establishes an independent formatting context, so absolutely-positioned children resolve against it.
- An infinite shimmer on resting chrome has an attention cost as well as a frame cost. This one is slow, low-contrast, and gone under
motion-reduce:. - Measure before and after. Containment and promotion are hypotheses about your page, not universal wins.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Tailwind v4 sets the floor. contain and will-change are widely supported and safely ignored where absent, so the performance work degrades to a plain glass bar rather than breaking.