05 / 21
All 21 in 21 Tailwind CSS Pricing Tables
- 01Tailwind CSS Pricing Table with Monthly / Annual Toggle
- 02Tailwind Pricing Table with Currency Switcher (USD, GBP, EUR, AUD)
- 03Tailwind CSS Pricing Comparison Table with Expandable Features
- 04Tailwind Dark Mode Pricing Cards with Light / Dark Toggle
- 05Tailwind Pricing Cards with Hover Scale Effect
- 06Tailwind "Most Popular" Pricing Card with Animated Border Beam
- 07Tailwind Pricing Cards with Animated Discount Badges
- 08Tailwind Pricing Table CTA Button Hover Animation
- 09Tailwind Pricing Cards with Color-Changing Hover Themes
- 10Tailwind CSS 3D Flip Pricing Cards
- 11Tailwind Pricing Slider Calculator for Per-Seat Pricing
- 12Tailwind Tabbed Pricing Table for Multiple Products
- 13Tailwind Pricing Cards with Usage Meters & Progress Bars
- 14Tailwind Bundle Pricing Calculator with Checkboxes
- 15Glassmorphism Pricing Cards in Tailwind CSS
- 16Tailwind Pricing Card with Animated Gradient Border on Hover
- 17Tailwind Pricing Cards with Corner Ribbon & Bookmark Banner
- 18Neumorphic Pricing Table in Tailwind CSS (Soft UI)
- 19Mobile Swipe Pricing Carousel with Tailwind Scroll Snap
- 20Responsive Tailwind Pricing Table that Stacks into an Accordion
- 21Tailwind Pricing Cards with Skeleton Loading Shimmer
Tailwind Pricing Cards with Hover Scale Effect
The classic conversion micro-interaction: hover or keyboard-focus any tier and it lifts, scales and deepens its shadow while its siblings ease back and desaturate. The sibling logic is v4's variant stacking — group-has-[article:hover]/g:not-hover:scale-96 — read left to right as “when any card in the grid is hovered, and this one isn't”.
Complete Tailwind CSS landing page templates in HTML, React, Next.js and Vue · from $49
Cruip · Affiliate link
The code
<section class="tpt-05 w-full min-h-svh grid place-items-center bg-tpt05-bg bg-[radial-gradient(70%_50%_at_50%_100%,var(--color-tpt05-glow),transparent)] px-5 py-16 font-tpt05-sans text-tpt05-ink antialiased" aria-label="Pricing cards with focus hover effect">
<div class="grid w-full max-w-5xl justify-items-center gap-11">
<h2 class="text-center text-[clamp(26px,3.8vw,40px)] font-extrabold tracking-[-0.03em]">Pick your pace</h2>
<div class="group/g grid w-full gap-6 md:grid-cols-3">
<article class="relative flex flex-col rounded-3xl border border-tpt05-line bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-0 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-mut uppercase">Lite</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$15<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>2 seats</li><li>Weekly reports</li><li>Email support</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-ink text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc focus-visible:bg-tpt05-acc focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Lite</a>
</article>
<article class="relative flex flex-col rounded-3xl border border-tpt05-acc/40 bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-35 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] md:scale-[1.03] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 group-has-[article:hover]/g:not-hover:after:opacity-0 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<span class="absolute -top-3 left-8 rounded-full bg-tpt05-acc px-3 py-1 text-[10.5px] font-bold tracking-[0.08em] text-white uppercase">Recommended</span>
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-acc-ink uppercase">Growth</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$39<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>10 seats</li><li>Daily reports</li><li>200+ integrations</li><li>Live chat support</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-acc text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc-ink focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Growth</a>
</article>
<article class="relative flex flex-col rounded-3xl border border-tpt05-line bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-0 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-mut uppercase">Scale</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$99<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>Unlimited seats</li><li>Real-time analytics</li><li>Dedicated manager</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-ink text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc focus-visible:bg-tpt05-acc focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Scale</a>
</article>
</div>
<p aria-hidden="true" class="rounded-full border border-tpt05-line bg-white/70 px-3.5 py-2 font-tpt05-mono text-[11.5px] text-tpt05-mut">group-has-[article:hover]/g:not-hover:scale-96 · hover:scale-105</p>
</div>
</section><section class="tpt-05 w-full min-h-svh grid place-items-center bg-tpt05-bg bg-[radial-gradient(70%_50%_at_50%_100%,var(--color-tpt05-glow),transparent)] px-5 py-16 font-tpt05-sans text-tpt05-ink antialiased" aria-label="Pricing cards with focus hover effect">
<div class="grid w-full max-w-5xl justify-items-center gap-11">
<h2 class="text-center text-[clamp(26px,3.8vw,40px)] font-extrabold tracking-[-0.03em]">Pick your pace</h2>
<div class="group/g grid w-full gap-6 md:grid-cols-3">
<article class="relative flex flex-col rounded-3xl border border-tpt05-line bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-0 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-mut uppercase">Lite</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$15<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>2 seats</li><li>Weekly reports</li><li>Email support</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-ink text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc focus-visible:bg-tpt05-acc focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Lite</a>
</article>
<article class="relative flex flex-col rounded-3xl border border-tpt05-acc/40 bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-35 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] md:scale-[1.03] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 group-has-[article:hover]/g:not-hover:after:opacity-0 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<span class="absolute -top-3 left-8 rounded-full bg-tpt05-acc px-3 py-1 text-[10.5px] font-bold tracking-[0.08em] text-white uppercase">Recommended</span>
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-acc-ink uppercase">Growth</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$39<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>10 seats</li><li>Daily reports</li><li>200+ integrations</li><li>Live chat support</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-acc text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc-ink focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Growth</a>
</article>
<article class="relative flex flex-col rounded-3xl border border-tpt05-line bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-0 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-mut uppercase">Scale</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$99<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>Unlimited seats</li><li>Real-time analytics</li><li>Dedicated manager</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-ink text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc focus-visible:bg-tpt05-acc focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Scale</a>
</article>
</div>
<p aria-hidden="true" class="rounded-full border border-tpt05-line bg-white/70 px-3.5 py-2 font-tpt05-mono text-[11.5px] text-tpt05-mut">group-has-[article:hover]/g:not-hover:scale-96 · hover:scale-105</p>
</div>
</section>@import "tailwindcss";
@theme {
--color-tpt05-bg: #f2f0f7;
--color-tpt05-bg: oklch(0.955 0.01 300);
--color-tpt05-glow: #e6dcfb;
--color-tpt05-glow: oklch(0.91 0.045 300);
--color-tpt05-ink: #1d1a26;
--color-tpt05-ink: oklch(0.22 0.02 295);
--color-tpt05-body: #4a4460;
--color-tpt05-body: oklch(0.42 0.04 295);
--color-tpt05-mut: #686280;
--color-tpt05-mut: oklch(0.51 0.04 295);
--color-tpt05-line: #e2dfeb;
--color-tpt05-line: oklch(0.91 0.012 295);
--color-tpt05-acc: #8b3fe0;
--color-tpt05-acc: oklch(0.55 0.22 300);
--color-tpt05-acc-ink: #6c28b8;
--color-tpt05-acc-ink: oklch(0.47 0.21 300);
--font-tpt05-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tpt05-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities. */
.tpt-05 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tpt05-bg: #f2f0f7;
--color-tpt05-bg: oklch(0.955 0.01 300);
--color-tpt05-glow: #e6dcfb;
--color-tpt05-glow: oklch(0.91 0.045 300);
--color-tpt05-ink: #1d1a26;
--color-tpt05-ink: oklch(0.22 0.02 295);
--color-tpt05-body: #4a4460;
--color-tpt05-body: oklch(0.42 0.04 295);
--color-tpt05-mut: #686280;
--color-tpt05-mut: oklch(0.51 0.04 295);
--color-tpt05-line: #e2dfeb;
--color-tpt05-line: oklch(0.91 0.012 295);
--color-tpt05-acc: #8b3fe0;
--color-tpt05-acc: oklch(0.55 0.22 300);
--color-tpt05-acc-ink: #6c28b8;
--color-tpt05-acc-ink: oklch(0.47 0.21 300);
--font-tpt05-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tpt05-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities. */
.tpt-05 {
width: 100%;
min-height: 100svh;
}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-tpt05-bg: #f2f0f7;
--color-tpt05-bg: oklch(0.955 0.01 300);
--color-tpt05-glow: #e6dcfb;
--color-tpt05-glow: oklch(0.91 0.045 300);
--color-tpt05-ink: #1d1a26;
--color-tpt05-ink: oklch(0.22 0.02 295);
--color-tpt05-body: #4a4460;
--color-tpt05-body: oklch(0.42 0.04 295);
--color-tpt05-mut: #686280;
--color-tpt05-mut: oklch(0.51 0.04 295);
--color-tpt05-line: #e2dfeb;
--color-tpt05-line: oklch(0.91 0.012 295);
--color-tpt05-acc: #8b3fe0;
--color-tpt05-acc: oklch(0.55 0.22 300);
--color-tpt05-acc-ink: #6c28b8;
--color-tpt05-acc-ink: oklch(0.47 0.21 300);
--font-tpt05-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tpt05-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities. */
.tpt-05 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tpt05-bg: #f2f0f7;
--color-tpt05-bg: oklch(0.955 0.01 300);
--color-tpt05-glow: #e6dcfb;
--color-tpt05-glow: oklch(0.91 0.045 300);
--color-tpt05-ink: #1d1a26;
--color-tpt05-ink: oklch(0.22 0.02 295);
--color-tpt05-body: #4a4460;
--color-tpt05-body: oklch(0.42 0.04 295);
--color-tpt05-mut: #686280;
--color-tpt05-mut: oklch(0.51 0.04 295);
--color-tpt05-line: #e2dfeb;
--color-tpt05-line: oklch(0.91 0.012 295);
--color-tpt05-acc: #8b3fe0;
--color-tpt05-acc: oklch(0.55 0.22 300);
--color-tpt05-acc-ink: #6c28b8;
--color-tpt05-acc-ink: oklch(0.47 0.21 300);
--font-tpt05-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tpt05-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities. */
.tpt-05 {
width: 100%;
min-height: 100svh;
}<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=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&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=Plus+Jakarta+Sans:wght@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.
.prc-05__grid:has(.prc-05__card:hover) .prc-05__card:not(:hover)became three stackedgroup-has-[article:hover]/g:not-hover:utilities on each card.- The original's
transform:translateY() scale()string became v4's independenttranslateandscaleproperties, transitioned together withtransition-[translate,scale,filter,opacity]. - UI upgrade from the CSS original: v4 gates
hover:behind(hover:hover), fixing the original's sticky zoomed card after a tap on iOS. - UI upgrade: Growth is pre-favoured at rest (lifted, tinted border, Recommended flag) and yields when a sibling is hovered; muted copy rose from
#8d87a0(3.4:1) to 5.4:1.
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 Pricing Cards with Hover Scale Effect
Source: https://codefronts.com/components/tailwind-css-pricing-tables/tailwind-pricing-cards-hover-scale-effect/
The classic conversion micro-interaction: hover or keyboard-focus any tier and it lifts, scales and deepens its shadow while its siblings ease back and desaturate. The sibling logic is v4's variant stacking — group-has-[article:hover]/g:not-hover:scale-96 — read left to right as “when any card in the grid is hovered, and this one isn't”.
## HTML
```html
<section class="tpt-05 w-full min-h-svh grid place-items-center bg-tpt05-bg bg-[radial-gradient(70%_50%_at_50%_100%,var(--color-tpt05-glow),transparent)] px-5 py-16 font-tpt05-sans text-tpt05-ink antialiased" aria-label="Pricing cards with focus hover effect">
<div class="grid w-full max-w-5xl justify-items-center gap-11">
<h2 class="text-center text-[clamp(26px,3.8vw,40px)] font-extrabold tracking-[-0.03em]">Pick your pace</h2>
<div class="group/g grid w-full gap-6 md:grid-cols-3">
<article class="relative flex flex-col rounded-3xl border border-tpt05-line bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-0 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-mut uppercase">Lite</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$15<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>2 seats</li><li>Weekly reports</li><li>Email support</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-ink text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc focus-visible:bg-tpt05-acc focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Lite</a>
</article>
<article class="relative flex flex-col rounded-3xl border border-tpt05-acc/40 bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-35 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] md:scale-[1.03] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 group-has-[article:hover]/g:not-hover:after:opacity-0 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<span class="absolute -top-3 left-8 rounded-full bg-tpt05-acc px-3 py-1 text-[10.5px] font-bold tracking-[0.08em] text-white uppercase">Recommended</span>
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-acc-ink uppercase">Growth</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$39<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>10 seats</li><li>Daily reports</li><li>200+ integrations</li><li>Live chat support</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-acc text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc-ink focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Growth</a>
</article>
<article class="relative flex flex-col rounded-3xl border border-tpt05-line bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-0 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-mut uppercase">Scale</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$99<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>Unlimited seats</li><li>Real-time analytics</li><li>Dedicated manager</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-ink text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc focus-visible:bg-tpt05-acc focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Scale</a>
</article>
</div>
<p aria-hidden="true" class="rounded-full border border-tpt05-line bg-white/70 px-3.5 py-2 font-tpt05-mono text-[11.5px] text-tpt05-mut">group-has-[article:hover]/g:not-hover:scale-96 · hover:scale-105</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tpt05-bg: #f2f0f7;
--color-tpt05-bg: oklch(0.955 0.01 300);
--color-tpt05-glow: #e6dcfb;
--color-tpt05-glow: oklch(0.91 0.045 300);
--color-tpt05-ink: #1d1a26;
--color-tpt05-ink: oklch(0.22 0.02 295);
--color-tpt05-body: #4a4460;
--color-tpt05-body: oklch(0.42 0.04 295);
--color-tpt05-mut: #686280;
--color-tpt05-mut: oklch(0.51 0.04 295);
--color-tpt05-line: #e2dfeb;
--color-tpt05-line: oklch(0.91 0.012 295);
--color-tpt05-acc: #8b3fe0;
--color-tpt05-acc: oklch(0.55 0.22 300);
--color-tpt05-acc-ink: #6c28b8;
--color-tpt05-acc-ink: oklch(0.47 0.21 300);
--font-tpt05-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tpt05-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities. */
.tpt-05 {
width: 100%;
min-height: 100svh;
}
```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 Pricing Cards with Hover Scale Effect
Source: https://codefronts.com/components/tailwind-css-pricing-tables/tailwind-pricing-cards-hover-scale-effect/
The classic conversion micro-interaction: hover or keyboard-focus any tier and it lifts, scales and deepens its shadow while its siblings ease back and desaturate. The sibling logic is v4's variant stacking — group-has-[article:hover]/g:not-hover:scale-96 — read left to right as “when any card in the grid is hovered, and this one isn't”.
## HTML
```html
<section class="tpt-05 w-full min-h-svh grid place-items-center bg-tpt05-bg bg-[radial-gradient(70%_50%_at_50%_100%,var(--color-tpt05-glow),transparent)] px-5 py-16 font-tpt05-sans text-tpt05-ink antialiased" aria-label="Pricing cards with focus hover effect">
<div class="grid w-full max-w-5xl justify-items-center gap-11">
<h2 class="text-center text-[clamp(26px,3.8vw,40px)] font-extrabold tracking-[-0.03em]">Pick your pace</h2>
<div class="group/g grid w-full gap-6 md:grid-cols-3">
<article class="relative flex flex-col rounded-3xl border border-tpt05-line bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-0 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-mut uppercase">Lite</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$15<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>2 seats</li><li>Weekly reports</li><li>Email support</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-ink text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc focus-visible:bg-tpt05-acc focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Lite</a>
</article>
<article class="relative flex flex-col rounded-3xl border border-tpt05-acc/40 bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-35 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] md:scale-[1.03] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 group-has-[article:hover]/g:not-hover:after:opacity-0 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<span class="absolute -top-3 left-8 rounded-full bg-tpt05-acc px-3 py-1 text-[10.5px] font-bold tracking-[0.08em] text-white uppercase">Recommended</span>
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-acc-ink uppercase">Growth</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$39<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>10 seats</li><li>Daily reports</li><li>200+ integrations</li><li>Live chat support</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-acc text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc-ink focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Growth</a>
</article>
<article class="relative flex flex-col rounded-3xl border border-tpt05-line bg-white p-8 transition-[translate,scale,filter,opacity] duration-350 ease-[cubic-bezier(.3,1.2,.3,1)] will-change-transform after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:opacity-0 after:shadow-[0_30px_60px_-22px_var(--color-tpt05-acc)] after:transition-opacity after:duration-350 after:content-[''] hover:z-10 hover:-translate-y-2.5 hover:scale-105 hover:after:opacity-60 focus-within:z-10 focus-within:-translate-y-2.5 focus-within:scale-105 focus-within:after:opacity-60 group-has-[article:hover]/g:not-hover:scale-96 group-has-[article:hover]/g:not-hover:opacity-75 group-has-[article:hover]/g:not-hover:saturate-50 motion-reduce:transition-none motion-reduce:hover:translate-y-0 motion-reduce:hover:scale-100">
<h3 class="text-[13px] font-bold tracking-[0.08em] text-tpt05-mut uppercase">Scale</h3>
<p class="mt-3 text-[46px] leading-none font-extrabold tracking-[-0.035em]">$99<small class="text-[15px] font-semibold tracking-normal text-tpt05-mut"> / month</small></p>
<ul class="mt-6 mb-7 grid flex-1 content-start gap-2.5 text-sm text-tpt05-body *:flex *:gap-2.5 *:before:font-bold *:before:text-tpt05-acc *:before:content-['✓']"><li>Unlimited seats</li><li>Real-time analytics</li><li>Dedicated manager</li></ul>
<a href="#" class="grid min-h-11 place-items-center rounded-xl bg-tpt05-ink text-sm font-bold text-white no-underline transition-colors hover:bg-tpt05-acc focus-visible:bg-tpt05-acc focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tpt05-acc">Select Scale</a>
</article>
</div>
<p aria-hidden="true" class="rounded-full border border-tpt05-line bg-white/70 px-3.5 py-2 font-tpt05-mono text-[11.5px] text-tpt05-mut">group-has-[article:hover]/g:not-hover:scale-96 · hover:scale-105</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tpt05-bg: #f2f0f7;
--color-tpt05-bg: oklch(0.955 0.01 300);
--color-tpt05-glow: #e6dcfb;
--color-tpt05-glow: oklch(0.91 0.045 300);
--color-tpt05-ink: #1d1a26;
--color-tpt05-ink: oklch(0.22 0.02 295);
--color-tpt05-body: #4a4460;
--color-tpt05-body: oklch(0.42 0.04 295);
--color-tpt05-mut: #686280;
--color-tpt05-mut: oklch(0.51 0.04 295);
--color-tpt05-line: #e2dfeb;
--color-tpt05-line: oklch(0.91 0.012 295);
--color-tpt05-acc: #8b3fe0;
--color-tpt05-acc: oklch(0.55 0.22 300);
--color-tpt05-acc-ink: #6c28b8;
--color-tpt05-acc-ink: oklch(0.47 0.21 300);
--font-tpt05-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tpt05-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities. */
.tpt-05 {
width: 100%;
min-height: 100svh;
}
```How this works
Variant stacking reads like a sentence. Each card carries its own recede rule:
group-has-[article:hover]/g:not-hover:scale-96
group-has-[article:hover]/g:not-hover:saturate-50
group-has-[article:hover]/g:not-hover:opacity-75Hover is already safe on touch. v4's hover: compiles inside @media (hover:hover), so a tap on a phone no longer leaves a card stuck in its zoomed state.
A favourite at rest. Growth starts slightly lifted (md:scale-[1.03]) and yields when a sibling is hovered — guiding the eye without taking the choice away.
Make it yours
- Lift strength:
hover:scale-105/hover:-translate-y-2.5. - How far siblings recede: the
not-hover:scale-96andsaturate-50values. - Remove the resting favourite by deleting
md:scale-[1.03]from Growth. - Shadow depth: restyle the
after:shadow-[…]freely — it never animates.
Gotchas — read before shipping
group-has-[…]:isn't a hover variant, so it isn't gated by(hover:hover); on touch it can't trigger anyway, since no card is ever hovered.- Keep
will-change-transformon the cards only, never on the grid. - Scaling a card over its neighbours needs
relative z-10on the hovered one or its shadow slides underneath.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Without :has() the sibling dim is skipped and the hovered card still lifts.