Pure TailwindMIT licensed

Tailwind Glassmorphism Product Card

Frosted glass, and Tailwind ships nearly all of it as core utilities: backdrop-blur-lg, backdrop-saturate-150, an alpha-white fill and a hairline alpha border. The only arbitrary values left are the composed outer+inset shadow and the bright top-edge highlight — the two parts that actually sell the pane of glass.

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time

Untitled UI React · Affiliate link

Get Untitled UI Pro

The code

<section class="tpc-07 w-full min-h-svh grid place-items-center font-tpc07-sans px-5 py-14 bg-[radial-gradient(50%_60%_at_15%_20%,oklch(0.7_0.2_20/0.9),transparent_60%),radial-gradient(50%_60%_at_85%_30%,oklch(0.72_0.2_260/0.9),transparent_60%),radial-gradient(60%_70%_at_60%_90%,oklch(0.75_0.19_180/0.85),transparent_60%),linear-gradient(135deg,oklch(0.28_0.09_300),oklch(0.18_0.06_285))]" aria-label="Glassmorphism product card demo">
  <article class="relative w-[19.375rem] max-w-full p-5.5 rounded-[22px] overflow-hidden bg-white/14 backdrop-blur-lg backdrop-saturate-150 border border-white/30 shadow-[0_30px_60px_-30px_oklch(0_0_0/0.5),inset_0_1px_0_oklch(1_0_0/0.4)] transition-[translate,box-shadow,border-color] duration-400 hover:-translate-y-1 hover:border-white/45 hover:shadow-[0_40px_70px_-30px_oklch(0_0_0/0.6),inset_0_1px_0_oklch(1_0_0/0.5)] focus-within:-translate-y-1 focus-within:border-white/45 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
    <span aria-hidden="true" class="absolute top-0 inset-x-[12%] h-px bg-linear-[90deg,transparent,oklch(1_0_0/0.8),transparent]"></span>
    <div role="img" aria-label="Product photo: Prism smart lamp" class="aspect-[16/10] rounded-[14px] border border-white/20 bg-linear-[135deg,oklch(1_0_0/0.3),oklch(1_0_0/0.08)] bg-[url('https://images.unsplash.com/photo-1513506003901-1e6a229e2d15?w=800&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
    <p class="mt-4 font-tpc07-mono text-[11px] tracking-[0.2em] uppercase text-white/80">New drop</p>
    <h3 class="mt-1.5 text-[20px] font-bold text-white [text-shadow:0_1px_6px_oklch(0_0_0/0.25)]">Prism Smart Lamp</h3>
    <p class="mt-1.5 text-[13.5px] leading-[1.5] text-white/85 text-pretty">16M colours, app-controlled, ambient sync.</p>
    <div class="mt-4.5 flex items-center justify-between gap-3">
      <p class="text-[22px] font-extrabold text-white tabular-nums">$89</p>
      <button type="button" class="min-h-11 h-11 px-5.5 rounded-xl border border-white/50 bg-white/90 text-tpc07-ink text-sm font-bold cursor-pointer transition-colors duration-200 hover:bg-white focus-visible:outline-3 focus-visible:outline-white/80 focus-visible:outline-offset-2 motion-reduce:transition-none">Add to Cart</button>
    </div>
  </article>
</section>
@import "tailwindcss";

@theme {
  --color-tpc07-ink: #241844;
  --color-tpc07-ink: oklch(0.25 0.08 295);
  --font-tpc07-sans: 'Outfit', system-ui, sans-serif;
  --font-tpc07-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tpc-07 {
  width: 100%;
  min-height: 100svh;
}

.tpc-07 ::selection {
  background: oklch(1 0 0 / 0.85);
  color: var(--color-tpc07-ink);
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<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.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tpc07-ink: #241844;
  --color-tpc07-ink: oklch(0.25 0.08 295);
  --font-tpc07-sans: 'Outfit', system-ui, sans-serif;
  --font-tpc07-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tpc-07 {
  width: 100%;
  min-height: 100svh;
}

.tpc-07 ::selection {
  background: oklch(1 0 0 / 0.85);
  color: var(--color-tpc07-ink);
}
3Fonts used by this demooptional — skip if you have your own type stack
<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=Outfit:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • This demo needed the fewest arbitrary values of any in the collection: backdrop-blur-lg, backdrop-saturate-150, bg-white/14 and border-white/30 cover four of the five glass properties.
  • The composed shadow stays one arbitrary value because the outer lift and the inset bevel are a single perceptual decision. Splitting them into shadow-* plus inset-shadow-* would let them drift out of sync on hover.
  • The ::before top highlight became an aria-hidden span. A before: variant would work, but the gradient is long enough that a real element reads better — and it needs no content-[''] incantation.
  • The gradient scene lives in the section's own class list rather than the stylesheet, which makes the dependency explicit: this card cannot be lifted onto a flat page and still be glass.
  • Enhancement over the CSS original: focus-within: twins for the lift, full-opacity ink on the CTA (the original's translucent white fill was borderline on a light backdrop) and text-pretty on the description.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
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 Glassmorphism Product Card
Source: https://codefronts.com/components/tailwind-css-product-cards/tailwind-glassmorphism-product-card/

Frosted glass, and Tailwind ships nearly all of it as core utilities: backdrop-blur-lg, backdrop-saturate-150, an alpha-white fill and a hairline alpha border. The only arbitrary values left are the composed outer+inset shadow and the bright top-edge highlight — the two parts that actually sell the pane of glass.
## HTML
```html
<section class="tpc-07 w-full min-h-svh grid place-items-center font-tpc07-sans px-5 py-14 bg-[radial-gradient(50%_60%_at_15%_20%,oklch(0.7_0.2_20/0.9),transparent_60%),radial-gradient(50%_60%_at_85%_30%,oklch(0.72_0.2_260/0.9),transparent_60%),radial-gradient(60%_70%_at_60%_90%,oklch(0.75_0.19_180/0.85),transparent_60%),linear-gradient(135deg,oklch(0.28_0.09_300),oklch(0.18_0.06_285))]" aria-label="Glassmorphism product card demo">
  <article class="relative w-[19.375rem] max-w-full p-5.5 rounded-[22px] overflow-hidden bg-white/14 backdrop-blur-lg backdrop-saturate-150 border border-white/30 shadow-[0_30px_60px_-30px_oklch(0_0_0/0.5),inset_0_1px_0_oklch(1_0_0/0.4)] transition-[translate,box-shadow,border-color] duration-400 hover:-translate-y-1 hover:border-white/45 hover:shadow-[0_40px_70px_-30px_oklch(0_0_0/0.6),inset_0_1px_0_oklch(1_0_0/0.5)] focus-within:-translate-y-1 focus-within:border-white/45 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
    <span aria-hidden="true" class="absolute top-0 inset-x-[12%] h-px bg-linear-[90deg,transparent,oklch(1_0_0/0.8),transparent]"></span>
    <div role="img" aria-label="Product photo: Prism smart lamp" class="aspect-[16/10] rounded-[14px] border border-white/20 bg-linear-[135deg,oklch(1_0_0/0.3),oklch(1_0_0/0.08)] bg-[url('https://images.unsplash.com/photo-1513506003901-1e6a229e2d15?w=800&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
    <p class="mt-4 font-tpc07-mono text-[11px] tracking-[0.2em] uppercase text-white/80">New drop</p>
    <h3 class="mt-1.5 text-[20px] font-bold text-white [text-shadow:0_1px_6px_oklch(0_0_0/0.25)]">Prism Smart Lamp</h3>
    <p class="mt-1.5 text-[13.5px] leading-[1.5] text-white/85 text-pretty">16M colours, app-controlled, ambient sync.</p>
    <div class="mt-4.5 flex items-center justify-between gap-3">
      <p class="text-[22px] font-extrabold text-white tabular-nums">$89</p>
      <button type="button" class="min-h-11 h-11 px-5.5 rounded-xl border border-white/50 bg-white/90 text-tpc07-ink text-sm font-bold cursor-pointer transition-colors duration-200 hover:bg-white focus-visible:outline-3 focus-visible:outline-white/80 focus-visible:outline-offset-2 motion-reduce:transition-none">Add to Cart</button>
    </div>
  </article>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tpc07-ink: #241844;
  --color-tpc07-ink: oklch(0.25 0.08 295);
  --font-tpc07-sans: 'Outfit', system-ui, sans-serif;
  --font-tpc07-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tpc-07 {
  width: 100%;
  min-height: 100svh;
}

.tpc-07 ::selection {
  background: oklch(1 0 0 / 0.85);
  color: var(--color-tpc07-ink);
}
```

How this works

Glass is four properties, and three are utilities now.

<div class="bg-white/14 backdrop-blur-lg backdrop-saturate-150
            border border-white/30
            shadow-[0_30px_60px_-30px_…,inset_0_1px_0_oklch(1_0_0/0.4)]">

The slash-alpha form (bg-white/14) is the real win over the CSS version's rgba(255,255,255,.14): the alpha is a number you can scan, and the colour stays a token.

The scene is part of the component. backdrop-filter blurs what is behind the element — on a flat background the entire effect is invisible. So the stage carries three radial gradients in oklch plus a base linear gradient, and the card is positioned over their intersection deliberately.

Contrast is the hard part. Text on glass sits over an unknown backdrop, so every string here is full-opacity white or a 0.82-alpha white at 13.5px minimum, the price is 800-weight, and the CTA is a solid near-white pill with dark ink — never a ghost button, which on glass is unreadable.

Make it yours

  • Frost thickness: backdrop-blur-md → backdrop-blur-xl, paired with the bg-white/14 alpha. More blur plus more alpha reads as thicker glass.
  • Recolour the scene, not the card: the three radial-gradient hues on the root set the entire mood.
  • Edge crispness: border-white/30 and the highlight span's alpha. Drop both for soft, frameless glass.
  • Add a second inset shadow layer for a heavier beveled-glass feel.
  • Dark glass: swap bg-white/14 for bg-black/25 and the ink to near-white — same utilities, opposite read.

Gotchas — read before shipping

  • backdrop-filter needs content behind it. Keep the gradient scene, or the card is just a translucent rectangle.
  • Safari needs -webkit-backdrop-filter; Tailwind emits it, but a hand-written fallback background still matters for engines that support neither.
  • Text contrast on glass is fragile. Never drop body copy below 0.8 alpha white, and never use a translucent CTA.
  • Nested backdrop-blur elements compound into a soup — blur the card, not the card AND its media frame.
  • A large blurred surface is expensive to paint. One hero card is fine; twelve in a grid is a scroll-jank complaint.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

backdrop-filter: Chrome 76+, Safari 9+ (prefixed), Firefox 103+. Where unsupported the card falls back to its translucent background, which is the graceful degradation.

Techniques used in this demo

Theme tokensset in @theme, used by a utility

HTML & JSno Tailwind involved

Search CodeFronts

Loading…