03 / 20
All 20 in 20 Tailwind Liquid Glass Effects
- 01Tailwind Liquid Glass Card with Hover Refraction
- 02Tailwind Liquid Glass Button with Glossy Highlight
- 03Tailwind Liquid Glass Navigation Bar
- 04Tailwind Liquid Gooey Toggle Switch
- 05Tailwind Liquid Glass Modal Dialog
- 06Tailwind Liquid Glass Theme Switcher
- 07Tailwind Liquid Glass Input Form Fields
- 08Tailwind SVG Displacement Liquid Glass Background
- 09Tailwind Liquid Glass Dropdown Menu
- 10Tailwind Liquid Glass Pricing Table
- 11Tailwind Liquid Glass Tooltip Popover
- 12Tailwind Liquid Glass Audio Player UI
- 13Tailwind Liquid Glass Range Slider
- 14Tailwind Liquid Glass Toast Notification
- 15Tailwind Liquid Glass Sidebar Navigation
- 16Tailwind Liquid Glass Accordion
- 17Tailwind Liquid Glass Login Card
- 18Tailwind Liquid Glass Floating Action Button
- 19Tailwind Liquid Glass Loading Skeleton
- 20Tailwind Liquid Glass Multi-Step Form Wizard
Tailwind Liquid Glass Navigation Bar
A sticky bar that turns into a frosted lens as content scrolls beneath it. The port's payoff is the active state: what was a [aria-current=page] attribute selector in a stylesheet becomes an aria-[current=page]: variant sitting on the link itself, so the pill treatment and the semantics that drive it are one line apart.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="lgt-03 relative h-svh min-h-svh w-full overflow-y-auto bg-lgt03-bg font-lgt03-sans" aria-label="Tailwind liquid glass navigation bar">
<header class="sticky top-0 z-10 flex items-center justify-between gap-5 border-b border-white/25 bg-white/10 px-[clamp(16px,4vw,32px)] py-3.5 backdrop-blur-[20px] backdrop-saturate-180 shadow-[inset_0_1px_0_rgba(255,255,255,.4),0_10px_30px_-20px_rgba(0,0,0,.8)]">
<span class="text-xl font-extrabold tracking-[-0.01em] text-white">Lumen</span>
<nav class="flex gap-1.5" aria-label="Primary">
<a href="#lgt-03-scroll" aria-current="page" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Home</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Work</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Studio</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Contact</a>
</nav>
</header>
<div id="lgt-03-scroll" class="mx-auto flex max-w-235 flex-col items-center gap-7 px-[clamp(16px,4vw,40px)] pt-7 pb-30">
<img src="https://picsum.photos/seed/lgnav-a/900/500" width="900" height="500" alt="Coastline at dawn" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
<h3 class="text-center text-2xl font-extrabold text-white">Scroll — watch content frost under the bar</h3>
<img src="https://picsum.photos/seed/lgnav-b/900/500" width="900" height="500" alt="City at night" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
<p class="max-w-[52ch] text-center text-base leading-relaxed text-white/75">The sticky bar samples and blurs whatever slides beneath it, in real time, on the compositor — no scroll listener, no JavaScript.</p>
<img src="https://picsum.photos/seed/lgnav-c/900/500" width="900" height="500" alt="Mountain range" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
</div>
</section><section class="lgt-03 relative h-svh min-h-svh w-full overflow-y-auto bg-lgt03-bg font-lgt03-sans" aria-label="Tailwind liquid glass navigation bar">
<header class="sticky top-0 z-10 flex items-center justify-between gap-5 border-b border-white/25 bg-white/10 px-[clamp(16px,4vw,32px)] py-3.5 backdrop-blur-[20px] backdrop-saturate-180 shadow-[inset_0_1px_0_rgba(255,255,255,.4),0_10px_30px_-20px_rgba(0,0,0,.8)]">
<span class="text-xl font-extrabold tracking-[-0.01em] text-white">Lumen</span>
<nav class="flex gap-1.5" aria-label="Primary">
<a href="#lgt-03-scroll" aria-current="page" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Home</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Work</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Studio</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Contact</a>
</nav>
</header>
<div id="lgt-03-scroll" class="mx-auto flex max-w-235 flex-col items-center gap-7 px-[clamp(16px,4vw,40px)] pt-7 pb-30">
<img src="https://picsum.photos/seed/lgnav-a/900/500" width="900" height="500" alt="Coastline at dawn" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
<h3 class="text-center text-2xl font-extrabold text-white">Scroll — watch content frost under the bar</h3>
<img src="https://picsum.photos/seed/lgnav-b/900/500" width="900" height="500" alt="City at night" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
<p class="max-w-[52ch] text-center text-base leading-relaxed text-white/75">The sticky bar samples and blurs whatever slides beneath it, in real time, on the compositor — no scroll listener, no JavaScript.</p>
<img src="https://picsum.photos/seed/lgnav-c/900/500" width="900" height="500" alt="Mountain range" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
</div>
</section>@import "tailwindcss";
@theme {
--color-lgt03-bg: #0e0b1a;
--color-lgt03-bg: oklch(0.16 0.03 295);
--font-lgt03-sans: 'Manrope', system-ui, sans-serif;
}@import "tailwindcss";
@theme {
--color-lgt03-bg: #0e0b1a;
--color-lgt03-bg: oklch(0.16 0.03 295);
--font-lgt03-sans: 'Manrope', system-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 {
--color-lgt03-bg: #0e0b1a;
--color-lgt03-bg: oklch(0.16 0.03 295);
--font-lgt03-sans: 'Manrope', system-ui, sans-serif;
}@import "tailwindcss";
@theme {
--color-lgt03-bg: #0e0b1a;
--color-lgt03-bg: oklch(0.16 0.03 295);
--font-lgt03-sans: 'Manrope', system-ui, sans-serif;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;800&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The active-state attribute selector becomes an
aria-[current=page]:variant, so the pill styling sits next to the ARIA attribute that justifies it. - Fluid padding is a single arbitrary
clamp()utility rather than a media query — the responsive behaviour is readable in the class list. - No JavaScript: the frost is compositor work triggered by
sticky, and adding a scroll listener to 'improve' it only costs INP. - The four glass utilities are identical to demo 01's, just at a different blur radius — the material is a vocabulary, not a per-component invention.
- Every image keeps its intrinsic
width/height, so the scroll body is CLS-free.
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 Liquid Glass Navigation Bar
Source: https://codefronts.com/design-styles/tailwind-liquid-glass-effects/tailwind-liquid-glass-navigation-bar/
A sticky bar that turns into a frosted lens as content scrolls beneath it. The port's payoff is the active state: what was a [aria-current=page] attribute selector in a stylesheet becomes an aria-[current=page]: variant sitting on the link itself, so the pill treatment and the semantics that drive it are one line apart.
## HTML
```html
<section class="lgt-03 relative h-svh min-h-svh w-full overflow-y-auto bg-lgt03-bg font-lgt03-sans" aria-label="Tailwind liquid glass navigation bar">
<header class="sticky top-0 z-10 flex items-center justify-between gap-5 border-b border-white/25 bg-white/10 px-[clamp(16px,4vw,32px)] py-3.5 backdrop-blur-[20px] backdrop-saturate-180 shadow-[inset_0_1px_0_rgba(255,255,255,.4),0_10px_30px_-20px_rgba(0,0,0,.8)]">
<span class="text-xl font-extrabold tracking-[-0.01em] text-white">Lumen</span>
<nav class="flex gap-1.5" aria-label="Primary">
<a href="#lgt-03-scroll" aria-current="page" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Home</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Work</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Studio</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Contact</a>
</nav>
</header>
<div id="lgt-03-scroll" class="mx-auto flex max-w-235 flex-col items-center gap-7 px-[clamp(16px,4vw,40px)] pt-7 pb-30">
<img src="https://picsum.photos/seed/lgnav-a/900/500" width="900" height="500" alt="Coastline at dawn" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
<h3 class="text-center text-2xl font-extrabold text-white">Scroll — watch content frost under the bar</h3>
<img src="https://picsum.photos/seed/lgnav-b/900/500" width="900" height="500" alt="City at night" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
<p class="max-w-[52ch] text-center text-base leading-relaxed text-white/75">The sticky bar samples and blurs whatever slides beneath it, in real time, on the compositor — no scroll listener, no JavaScript.</p>
<img src="https://picsum.photos/seed/lgnav-c/900/500" width="900" height="500" alt="Mountain range" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-lgt03-bg: #0e0b1a;
--color-lgt03-bg: oklch(0.16 0.03 295);
--font-lgt03-sans: 'Manrope', system-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 Liquid Glass Navigation Bar
Source: https://codefronts.com/design-styles/tailwind-liquid-glass-effects/tailwind-liquid-glass-navigation-bar/
A sticky bar that turns into a frosted lens as content scrolls beneath it. The port's payoff is the active state: what was a [aria-current=page] attribute selector in a stylesheet becomes an aria-[current=page]: variant sitting on the link itself, so the pill treatment and the semantics that drive it are one line apart.
## HTML
```html
<section class="lgt-03 relative h-svh min-h-svh w-full overflow-y-auto bg-lgt03-bg font-lgt03-sans" aria-label="Tailwind liquid glass navigation bar">
<header class="sticky top-0 z-10 flex items-center justify-between gap-5 border-b border-white/25 bg-white/10 px-[clamp(16px,4vw,32px)] py-3.5 backdrop-blur-[20px] backdrop-saturate-180 shadow-[inset_0_1px_0_rgba(255,255,255,.4),0_10px_30px_-20px_rgba(0,0,0,.8)]">
<span class="text-xl font-extrabold tracking-[-0.01em] text-white">Lumen</span>
<nav class="flex gap-1.5" aria-label="Primary">
<a href="#lgt-03-scroll" aria-current="page" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Home</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Work</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Studio</a>
<a href="#lgt-03-scroll" class="rounded-full px-3.5 py-2 text-sm font-semibold text-white/85 no-underline transition-colors duration-200 hover:bg-white/16 hover:text-white focus-visible:bg-white/16 focus-visible:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white aria-[current=page]:bg-white aria-[current=page]:text-lgt03-bg">Contact</a>
</nav>
</header>
<div id="lgt-03-scroll" class="mx-auto flex max-w-235 flex-col items-center gap-7 px-[clamp(16px,4vw,40px)] pt-7 pb-30">
<img src="https://picsum.photos/seed/lgnav-a/900/500" width="900" height="500" alt="Coastline at dawn" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
<h3 class="text-center text-2xl font-extrabold text-white">Scroll — watch content frost under the bar</h3>
<img src="https://picsum.photos/seed/lgnav-b/900/500" width="900" height="500" alt="City at night" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
<p class="max-w-[52ch] text-center text-base leading-relaxed text-white/75">The sticky bar samples and blurs whatever slides beneath it, in real time, on the compositor — no scroll listener, no JavaScript.</p>
<img src="https://picsum.photos/seed/lgnav-c/900/500" width="900" height="500" alt="Mountain range" class="block h-auto w-full rounded-[18px] shadow-[0_20px_44px_-24px_rgba(0,0,0,.7)]">
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-lgt03-bg: #0e0b1a;
--color-lgt03-bg: oklch(0.16 0.03 295);
--font-lgt03-sans: 'Manrope', system-ui, sans-serif;
}
```How this works
Sticky, not fixed. sticky top-0 keeps the bar in flow, so it reserves its own space and adds nothing to Cumulative Layout Shift. Everything that scrolls under it is sampled, blurred and colour-boosted by the compositor — no scroll handler, no class toggling, no JavaScript at all.
class="sticky top-0 z-10 flex items-center justify-between
border-b border-white/25 bg-white/10
backdrop-blur-[20px] backdrop-saturate-180
shadow-[inset_0_1px_0_rgba(255,255,255,.4),0_10px_30px_-20px_rgba(0,0,0,.8)]"The active link is driven by ARIA, not by a class. aria-[current=page]: reads the attribute the screen reader already needs, which means the visual state and the announced state can never drift apart. This is the port's best structural improvement over the CSS original.
Saturation is what makes it look like glass rather than fog. Blur alone desaturates whatever is behind it; backdrop-saturate-180 pushes the colour back up so photographs stay vivid through the bar. Dropping it is the fastest way to make a frosted navbar look cheap.
Make it yours
- Dial the material with the blur radius and saturation pair;
backdrop-blur-md backdrop-saturate-150is a subtler, more corporate setting. - Switch to smoked glass for light pages:
bg-black/20withborder-white/10and light text. - Restyle the active pill entirely inside the
aria-[current=page]:chain — no new selector, no new rule. - Make the bar taller and airier by editing the single
py-3.5, or fully fluid withpy-[clamp(10px,2vh,20px)]. - Add a scrolled-past state with a tiny IntersectionObserver that flips a
data-scrolledattribute, then style it withdata-scrolled:shadow-lg.
Gotchas — read before shipping
- A sticky bar only frosts what actually scrolls under it — if your page is short the effect never appears. The demo ships a tall scroll body for exactly this reason.
z-10matters: without a stacking order the blurred bar can be painted under later siblings that create their own contexts.- Do not make the fill opaque to 'fix' contrast. Raise the tint to
bg-white/16and keep the text at full opacity instead. aria-[current=page]needs the literal attribute on the link. Setting a class instead loses the accessibility half of the win.- Images without
width/heightreintroduce CLS the sticky bar was avoiding in the first place. - backdrop-filter on a sticky element can flicker in older iOS Safari; a
transform: translateZ(0)nudge (as[transform:translateZ(0)]) settles it.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Utilities only, no JavaScript. position:sticky is universal; where backdrop-filter is unavailable the bar degrades to a lightly tinted solid header that is still perfectly functional.