Tailwind v4MIT licensed

Tailwind Liquid Glass Pricing Table

Three tiers where only the Pro card is alive: a conic rim rotates around it and its badge pulses, while the flanking plans stay calm frosted glass. The port makes the hierarchy legible as a diff — all three cards share one class string, and Pro adds exactly four utilities.

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="lgt-10 grid w-full min-h-svh place-items-center p-15 font-lgt10-sans [background:radial-gradient(circle_at_20%_20%,#3a1f5a,#160f2c_60%),radial-gradient(circle_at_80%_80%,#1f3a5a,#160f2c_60%)]" aria-label="Tailwind liquid glass pricing table">
  <div class="grid w-[min(920px,100%)] items-center gap-5.5 grid-cols-[repeat(auto-fit,minmax(min(240px,100%),1fr))]">

    <article class="relative rounded-[22px] border border-white/20 bg-white/8 px-6.5 py-7.5 text-white backdrop-blur-[18px] backdrop-saturate-160 shadow-[inset_0_1px_0_rgba(255,255,255,.3),0_20px_44px_-26px_rgba(0,0,0,.6)]">
      <h3 class="mb-2.5 text-[15px] font-bold uppercase tracking-[0.06em] text-white/80">Starter</h3>
      <p class="mb-5 text-[15px] text-white/70"><span class="text-[40px] font-black tracking-[-0.02em] text-white">$0</span>/mo</p>
      <ul class="mb-6 flex list-none flex-col gap-2.75 p-0">
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">3 projects</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">Community support</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">1 GB storage</li>
      </ul>
      <button type="button" class="w-full cursor-pointer rounded-[12px] border border-white/30 bg-white/12 py-3.25 text-[15px] font-bold text-white transition-[background-color,transform] duration-200 hover:-translate-y-0.5 hover:bg-white/20 focus-visible:-translate-y-0.5 focus-visible:bg-white/20 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-white motion-reduce:transition-none">Choose Starter</button>
    </article>

    <article class="relative z-2 -translate-y-3.5 rounded-[22px] border border-white/20 bg-white/15 px-6.5 py-7.5 text-white backdrop-blur-[18px] backdrop-saturate-160 shadow-[inset_0_1px_0_rgba(255,255,255,.3),0_20px_44px_-26px_rgba(0,0,0,.6)] before:pointer-events-none before:absolute before:-inset-[1.5px] before:rounded-[inherit] before:p-[1.5px] before:animate-lgt10-spin before:[background:conic-gradient(from_var(--lgt-10-angle),var(--color-lgt10-pro),oklch(0.72_0.17_200),oklch(0.75_0.18_340),var(--color-lgt10-pro))] before:[mask-image:linear-gradient(#000_0_0),linear-gradient(#000_0_0)] before:[mask-clip:content-box,border-box] before:[mask-composite:exclude] motion-reduce:before:animate-none">
      <span class="absolute -top-3.25 left-1/2 -translate-x-1/2 animate-lgt10-glow rounded-full bg-lgt10-pro px-3.5 py-1.5 text-[11px] font-extrabold uppercase tracking-[0.08em] text-white motion-reduce:animate-none">Most popular</span>
      <h3 class="mb-2.5 text-[15px] font-bold uppercase tracking-[0.06em] text-white/80">Pro</h3>
      <p class="mb-5 text-[15px] text-white/70"><span class="text-[40px] font-black tracking-[-0.02em] text-white">$24</span>/mo</p>
      <ul class="mb-6 flex list-none flex-col gap-2.75 p-0">
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">Unlimited projects</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">Priority support</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">100 GB storage</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">Advanced analytics</li>
      </ul>
      <button type="button" class="w-full cursor-pointer rounded-[12px] border border-lgt10-pro/60 bg-linear-to-b from-lgt10-pro-top to-lgt10-pro py-3.25 text-[15px] font-bold text-white transition-[filter,transform] duration-200 hover:-translate-y-0.5 hover:brightness-110 focus-visible:-translate-y-0.5 focus-visible:brightness-110 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-white motion-reduce:transition-none">Choose Pro</button>
    </article>

    <article class="relative rounded-[22px] border border-white/20 bg-white/8 px-6.5 py-7.5 text-white backdrop-blur-[18px] backdrop-saturate-160 shadow-[inset_0_1px_0_rgba(255,255,255,.3),0_20px_44px_-26px_rgba(0,0,0,.6)]">
      <h3 class="mb-2.5 text-[15px] font-bold uppercase tracking-[0.06em] text-white/80">Team</h3>
      <p class="mb-5 text-[15px] text-white/70"><span class="text-[40px] font-black tracking-[-0.02em] text-white">$69</span>/mo</p>
      <ul class="mb-6 flex list-none flex-col gap-2.75 p-0">
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">Everything in Pro</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">SSO &amp; roles</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">1 TB storage</li>
      </ul>
      <button type="button" class="w-full cursor-pointer rounded-[12px] border border-white/30 bg-white/12 py-3.25 text-[15px] font-bold text-white transition-[background-color,transform] duration-200 hover:-translate-y-0.5 hover:bg-white/20 focus-visible:-translate-y-0.5 focus-visible:bg-white/20 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-white motion-reduce:transition-none">Choose Team</button>
    </article>

  </div>
</section>
@import "tailwindcss";

@property --lgt-10-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

@theme {
  --color-lgt10-pro: #9b5cf0;
  --color-lgt10-pro: oklch(0.66 0.2 300);
  --color-lgt10-pro-top: #b47ef5;
  --color-lgt10-pro-top: oklch(0.72 0.17 300);
  --color-lgt10-check: #6ee7b7;
  --color-lgt10-check: oklch(0.78 0.16 160);
  --font-lgt10-sans: 'Manrope', system-ui, sans-serif;
  --animate-lgt10-spin: lgt-10-spin 5s linear infinite;
  --animate-lgt10-glow: lgt-10-glow 2.4s ease-in-out infinite;
}

@keyframes lgt-10-spin {
  to {
    --lgt-10-angle: 360deg;
  }
}

@keyframes lgt-10-glow {
  0%,
    100% {
    box-shadow: 0 0 0 1px rgb(255 255 255 / 0.3), 0 0 16px 1px color-mix(in oklab, var(--color-lgt10-pro) 60%, transparent);
  }

  50% {
    box-shadow: 0 0 0 1px rgb(255 255 255 / 0.4), 0 0 30px 4px color-mix(in oklab, var(--color-lgt10-pro) 80%, transparent);
  }
}

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";

@property --lgt-10-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

@theme {
  --color-lgt10-pro: #9b5cf0;
  --color-lgt10-pro: oklch(0.66 0.2 300);
  --color-lgt10-pro-top: #b47ef5;
  --color-lgt10-pro-top: oklch(0.72 0.17 300);
  --color-lgt10-check: #6ee7b7;
  --color-lgt10-check: oklch(0.78 0.16 160);
  --font-lgt10-sans: 'Manrope', system-ui, sans-serif;
  --animate-lgt10-spin: lgt-10-spin 5s linear infinite;
  --animate-lgt10-glow: lgt-10-glow 2.4s ease-in-out infinite;
}

@keyframes lgt-10-spin {
  to {
    --lgt-10-angle: 360deg;
  }
}

@keyframes lgt-10-glow {
  0%,
    100% {
    box-shadow: 0 0 0 1px rgb(255 255 255 / 0.3), 0 0 16px 1px color-mix(in oklab, var(--color-lgt10-pro) 60%, transparent);
  }

  50% {
    box-shadow: 0 0 0 1px rgb(255 255 255 / 0.4), 0 0 30px 4px color-mix(in oklab, var(--color-lgt10-pro) 80%, transparent);
  }
}
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=Manrope:wght@400;600;800&display=swap">

What changed in the port

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

  • All three cards share one glass class string; the Pro tier is four extra utilities, so the hierarchy is a diff rather than a modifier class.
  • The masked conic rim is the same idiom as demo 07 at a tighter inset — reusing techniques is what makes twenty demos feel like one system.
  • The whole responsive grid is a single grid-cols-[repeat(auto-fit,minmax(min(240px,100%),1fr))] utility with no media queries.
  • Check bullets are before:content-['&#10003;'] utilities on the list items, replacing a separate ::before rule.
  • Both loops are --animate-* theme entries and both carry motion-reduce:animate-none, leaving a static rim that still marks the tier.
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 Liquid Glass Pricing Table
Source: https://codefronts.com/design-styles/tailwind-liquid-glass-effects/tailwind-liquid-glass-pricing-table/

Three tiers where only the Pro card is alive: a conic rim rotates around it and its badge pulses, while the flanking plans stay calm frosted glass. The port makes the hierarchy legible as a diff &mdash; all three cards share one class string, and Pro adds exactly four utilities.
## HTML
```html
<section class="lgt-10 grid w-full min-h-svh place-items-center p-15 font-lgt10-sans [background:radial-gradient(circle_at_20%_20%,#3a1f5a,#160f2c_60%),radial-gradient(circle_at_80%_80%,#1f3a5a,#160f2c_60%)]" aria-label="Tailwind liquid glass pricing table">
  <div class="grid w-[min(920px,100%)] items-center gap-5.5 grid-cols-[repeat(auto-fit,minmax(min(240px,100%),1fr))]">

    <article class="relative rounded-[22px] border border-white/20 bg-white/8 px-6.5 py-7.5 text-white backdrop-blur-[18px] backdrop-saturate-160 shadow-[inset_0_1px_0_rgba(255,255,255,.3),0_20px_44px_-26px_rgba(0,0,0,.6)]">
      <h3 class="mb-2.5 text-[15px] font-bold uppercase tracking-[0.06em] text-white/80">Starter</h3>
      <p class="mb-5 text-[15px] text-white/70"><span class="text-[40px] font-black tracking-[-0.02em] text-white">$0</span>/mo</p>
      <ul class="mb-6 flex list-none flex-col gap-2.75 p-0">
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">3 projects</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">Community support</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">1 GB storage</li>
      </ul>
      <button type="button" class="w-full cursor-pointer rounded-[12px] border border-white/30 bg-white/12 py-3.25 text-[15px] font-bold text-white transition-[background-color,transform] duration-200 hover:-translate-y-0.5 hover:bg-white/20 focus-visible:-translate-y-0.5 focus-visible:bg-white/20 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-white motion-reduce:transition-none">Choose Starter</button>
    </article>

    <article class="relative z-2 -translate-y-3.5 rounded-[22px] border border-white/20 bg-white/15 px-6.5 py-7.5 text-white backdrop-blur-[18px] backdrop-saturate-160 shadow-[inset_0_1px_0_rgba(255,255,255,.3),0_20px_44px_-26px_rgba(0,0,0,.6)] before:pointer-events-none before:absolute before:-inset-[1.5px] before:rounded-[inherit] before:p-[1.5px] before:animate-lgt10-spin before:[background:conic-gradient(from_var(--lgt-10-angle),var(--color-lgt10-pro),oklch(0.72_0.17_200),oklch(0.75_0.18_340),var(--color-lgt10-pro))] before:[mask-image:linear-gradient(#000_0_0),linear-gradient(#000_0_0)] before:[mask-clip:content-box,border-box] before:[mask-composite:exclude] motion-reduce:before:animate-none">
      <span class="absolute -top-3.25 left-1/2 -translate-x-1/2 animate-lgt10-glow rounded-full bg-lgt10-pro px-3.5 py-1.5 text-[11px] font-extrabold uppercase tracking-[0.08em] text-white motion-reduce:animate-none">Most popular</span>
      <h3 class="mb-2.5 text-[15px] font-bold uppercase tracking-[0.06em] text-white/80">Pro</h3>
      <p class="mb-5 text-[15px] text-white/70"><span class="text-[40px] font-black tracking-[-0.02em] text-white">$24</span>/mo</p>
      <ul class="mb-6 flex list-none flex-col gap-2.75 p-0">
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">Unlimited projects</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">Priority support</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">100 GB storage</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">Advanced analytics</li>
      </ul>
      <button type="button" class="w-full cursor-pointer rounded-[12px] border border-lgt10-pro/60 bg-linear-to-b from-lgt10-pro-top to-lgt10-pro py-3.25 text-[15px] font-bold text-white transition-[filter,transform] duration-200 hover:-translate-y-0.5 hover:brightness-110 focus-visible:-translate-y-0.5 focus-visible:brightness-110 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-white motion-reduce:transition-none">Choose Pro</button>
    </article>

    <article class="relative rounded-[22px] border border-white/20 bg-white/8 px-6.5 py-7.5 text-white backdrop-blur-[18px] backdrop-saturate-160 shadow-[inset_0_1px_0_rgba(255,255,255,.3),0_20px_44px_-26px_rgba(0,0,0,.6)]">
      <h3 class="mb-2.5 text-[15px] font-bold uppercase tracking-[0.06em] text-white/80">Team</h3>
      <p class="mb-5 text-[15px] text-white/70"><span class="text-[40px] font-black tracking-[-0.02em] text-white">$69</span>/mo</p>
      <ul class="mb-6 flex list-none flex-col gap-2.75 p-0">
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">Everything in Pro</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">SSO &amp; roles</li>
        <li class="relative pl-6 text-sm text-white before:absolute before:left-0 before:font-extrabold before:text-lgt10-check before:content-['&#10003;']">1 TB storage</li>
      </ul>
      <button type="button" class="w-full cursor-pointer rounded-[12px] border border-white/30 bg-white/12 py-3.25 text-[15px] font-bold text-white transition-[background-color,transform] duration-200 hover:-translate-y-0.5 hover:bg-white/20 focus-visible:-translate-y-0.5 focus-visible:bg-white/20 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-white motion-reduce:transition-none">Choose Team</button>
    </article>

  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@property --lgt-10-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

@theme {
  --color-lgt10-pro: #9b5cf0;
  --color-lgt10-pro: oklch(0.66 0.2 300);
  --color-lgt10-pro-top: #b47ef5;
  --color-lgt10-pro-top: oklch(0.72 0.17 300);
  --color-lgt10-check: #6ee7b7;
  --color-lgt10-check: oklch(0.78 0.16 160);
  --font-lgt10-sans: 'Manrope', system-ui, sans-serif;
  --animate-lgt10-spin: lgt-10-spin 5s linear infinite;
  --animate-lgt10-glow: lgt-10-glow 2.4s ease-in-out infinite;
}

@keyframes lgt-10-spin {
  to {
    --lgt-10-angle: 360deg;
  }
}

@keyframes lgt-10-glow {
  0%,
    100% {
    box-shadow: 0 0 0 1px rgb(255 255 255 / 0.3), 0 0 16px 1px color-mix(in oklab, var(--color-lgt10-pro) 60%, transparent);
  }

  50% {
    box-shadow: 0 0 0 1px rgb(255 255 255 / 0.4), 0 0 30px 4px color-mix(in oklab, var(--color-lgt10-pro) 80%, transparent);
  }
}
```

How this works

Hierarchy as a diff. Every card carries the same glass utilities. The Pro card adds a heavier tint, a lift, a stacking bump and the animated rim — four utilities that you can read at a glance:

<!-- all three -->
class="rounded-[22px] border border-white/20 bg-white/8
       backdrop-blur-[18px] backdrop-saturate-160"

<!-- Pro adds -->
class="bg-white/15 -translate-y-3.5 z-2 before:animate-lgt10-spin"

The rotating rim is the same masked-conic idiom as the form fields, at a tighter 1.5px inset. Reusing the idiom rather than inventing a second one is what makes a twenty-demo collection feel like a system: learn it once in demo 07, recognise it instantly here.

Only one card animates, deliberately. Animating all three would cost three times the paint and dilute the signal to zero. The premium tier is the only thing moving on the screen, which is precisely why the eye goes there.

The grid needs no breakpoints. auto-fit with a minmax(min(240px,100%),1fr) track reflows from three columns to one on its own, and the min() guard stops the track overflowing on narrow phones.

Make it yours

  • Move the premium treatment to another tier by moving those four utilities — there is no --featured modifier class to maintain.
  • Recolour the rim through the conic gradient's stops, or make it monochrome for a more restrained enterprise look.
  • Slow the rotation to 8s in --animate-lgt10-spin; fast rims read as a sale banner, slow rims read as premium.
  • Drop the badge pulse entirely if the page already has motion — the rim alone marks the tier.
  • Add a fourth tier and the grid handles it with no changes at all.

Gotchas — read before shipping

  • @property is required for the rim to rotate; without it the gradient is static. That is an acceptable fallback, but know that you are relying on it.
  • Animate one card, not three. Three rotating rims triple the paint cost and destroy the hierarchy the effect exists to create.
  • The before: rim needs rounded-[inherit] or it squares off the corners of a rounded card.
  • Price and feature text must clear contrast on every tint — the Pro card's heavier bg-white/15 is a different background from its neighbours.
  • A pulsing glow next to a price is a persuasion pattern; use it where it is honest, and remember it disappears under motion-reduce.
  • -translate-y-3.5 lifts the Pro card out of alignment with its siblings' baselines — check the CTA row still reads as a row.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

backdrop-filter is broadly supported; the rotating rim needs @property (Chrome 85+, Safari 16.4+, Firefox 128+), degrading to a static gradient rim where absent. The table stays fully readable in every case.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Plain CSSno Tailwind surface

Search CodeFronts

Loading…