Glassmorphism in Tailwind CSS v4: A Practical Guide with Copy-Paste Examples
How to build real frosted-glass UI in Tailwind v4 — backdrop-filter, saturation, borders, shadows, and the accessibility pitfalls nobody talks about. With copy-paste code.
Glassmorphism — frosted glass over a busy background — is one of the most-requested UI effects. Done right, it adds depth and layering. Done wrong, it's illegible text floating over a blur. This guide covers the real implementation in Tailwind CSS v4, the accessibility requirements, and the common mistakes.
The core recipe
Glassmorphism is four properties working together:
- Semi-transparent background (rgba with 50-70% opacity)
- backdrop-filter: blur + saturate (the frosted effect)
- 1px border at low opacity (the 'glass edge')
- A subtle shadow (depth separation from the background)
Basic glass card in Tailwind v4
<div class="bg-white/60 backdrop-blur-lg backdrop-saturate-150
border border-white/20 rounded-2xl shadow-lg p-6">
<h3 class="text-lg font-semibold text-slate-900">Glass card</h3>
<p class="text-slate-700 mt-2">This only works over a busy background.</p>
</div>Glassmorphism requires a visually busy background behind the element. On a flat/empty background, the blur has nothing to blur — it looks broken. Always test with a real gradient, image, or pattern behind it.
Live example
Dark glass
For dark UIs, use a dark semi-transparent background instead of white. The blur still works — it just picks up darker tones.
<div class="bg-slate-900/50 backdrop-blur-xl backdrop-saturate-150
border border-white/10 rounded-2xl shadow-2xl p-6">
<h3 class="text-lg font-semibold text-white">Dark glass</h3>
<p class="text-slate-300 mt-2">Premium dark UI with depth.</p>
</div>Glassmorphism pill buttons
Pill-shaped glass buttons work well for navbars and CTAs sitting over a busy hero. Keep the blur low (4-8px) so the text stays readable.
<button class="bg-white/10 backdrop-blur-md border border-white/20
rounded-full px-5 py-2.5 text-white text-sm font-medium
hover:bg-white/20 transition-colors">
Get started
</button>Accessibility: the part most guides skip
Glassmorphism has a real accessibility cost. Here's what to check:
1. Contrast must pass WCAG AA against the BUSIEST area
Don't test your text against the average background — test it against the lightest region the blur might reveal. If the background has a white area, your text needs to pass 4.5:1 against white, not against the blurred average.
2. The border is not decoration — it's a separation channel
If the blur is heavy and the background is busy, the glass card can visually merge with its surroundings. The 1px border at 20% opacity is the visual separator that keeps the card readable. Never remove it 'because it looks cleaner.'
3. backdrop-filter needs a fallback
Older browsers (and some current ones) don't support backdrop-filter. Always provide a solid fallback background:
.glass-card {
/* Fallback for no backdrop-filter support */
background: rgba(255, 255, 255, 0.9);
}
@supports (backdrop-filter: blur(12px)) {
.glass-card {
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(12px) saturate(150%);
}
}4. Reduced motion: disable animated glass
If your glass element has an animated background (mesh gradient that shifts, for example), respect prefers-reduced-motion:
@media (prefers-reduced-motion: reduce) {
.glass-card {
animation: none;
transition: none;
}
}Common mistakes
- Too transparent (opacity < 0.4): text becomes unreadable against busy backgrounds. Stay above 0.5.
- Too much blur (>20px): the background becomes unrecognizable and the effect reads as 'frosted plastic,' not 'glass.' Stay between 8-16px.
- No border: the card merges with the background. Always include a 1px border at 10-30% opacity.
- Glass on glass: stacking two glass elements creates a muddy double-blur. Use solid surfaces for nested elements.
- Glass on empty backgrounds: if there's nothing behind the card to blur, the effect is invisible. Glassmorphism needs visual content behind it.
The full production snippet
Here's a complete, accessible, fallback-supported glass card you can drop into any Tailwind v4 project:
<!-- Glass card with fallback, a11y, and reduced-motion support -->
<div class="relative">
<!-- Fallback background (shown when backdrop-filter is unsupported) -->
<div class="absolute inset-0 bg-white/90 rounded-2xl"></div>
<!-- Glass layer -->
<div class="relative bg-white/60 backdrop-blur-lg backdrop-saturate-150
border border-white/20 rounded-2xl shadow-lg p-6
motion-safe:transition-transform hover:scale-[1.01]">
<h3 class="text-lg font-semibold text-slate-900">Production glass</h3>
<p class="text-slate-700 mt-2 text-sm">
Accessible. Has a fallback. Respects reduced motion.
</p>
<button class="mt-4 bg-violet-600 hover:bg-violet-700
text-white text-sm font-medium px-4 py-2
rounded-lg focus-visible:outline-2
focus-visible:outline-violet-600
focus-visible:outline-offset-2
transition-colors">
Action
</button>
</div>
</div>Glassmorphism is a tool, not a design system. Use it where depth and layering add clarity — over busy hero backgrounds, in floating navbars, in modal overlays. Don't use it everywhere. And always verify contrast with the GradientDeck check_contrast tool at gradientdeck.com/mcp.