17 / 24
All 24 in 24 Tailwind CSS Radio Buttons
- 01Tailwind Radio Button Cards (Selectable Cards)
- 02Tailwind Pill Radio Toggle (Segmented Control)
- 03Tailwind Radio Button with Icon and Description
- 04Tailwind Dark Mode Glowing Radio Button
- 05Accessible Tailwind Radio Button (appearance-none)
- 06Tailwind Radio Group with Badges
- 07Tailwind Animated Radio Button (Concentric Ripple)
- 08Tailwind Sliding Pill Radio Switch
- 09Tailwind 3D Sphere Radio Buttons
- 10Tailwind Ink Splash Radio Animation
- 11Tailwind Star Rating Radio Buttons
- 12Tailwind 3D Tilt Card Radio Selector
- 13Minimal Checkmark Radio Button in Tailwind
- 14Tailwind Color Swatch Radio Picker
- 15Tailwind Segmented Control Bar (View Switcher)
- 16Tailwind Neon Cyberpunk Radio Buttons
- 17Tailwind Pricing Plan Radio Cards
- 18Tailwind Liquid Wave Fill Radio Button
- 19Tailwind Image Radio Button Selector (Arch Mask)
- 20Tailwind Animated Gradient Border Radio Cards
- 21Tailwind Avatar Radio Picker (Profile Selector)
- 22Tailwind Stacked Radio List (Payment Method)
- 23Tailwind 3D Push Button Radio (Tactile Keys)
- 24Tailwind Pulsing Glow Radio Button (Status Picker)
Tailwind Pricing Plan Radio Cards
A complete pricing-table selector: three plan cards with price, features and a "Recommended" crown — each card a radio, so the whole table is one submittable form control. The Select / Selected ✓ pill is two spans stacked with [grid-area:1/1] and cross-faded by group-has-checked:; the summary line under the table follows the value.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="trb-17 w-full min-h-svh grid place-items-center bg-trb17-bg px-6 py-14 font-trb17-sans text-trb17-ink" aria-label="Subscription pricing plan cards demo">
<fieldset class="group/plans grid justify-items-center">
<legend class="text-center text-[28px] font-extrabold tracking-[-0.025em]">Pick your plan</legend>
<div class="mt-8 flex flex-wrap justify-center gap-[18px]">
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-line bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="starter" class="sr-only">
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Starter</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$0<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>3 projects</li><li>Community support</li><li>1 GB storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-acc/35 bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="pro" class="sr-only" checked>
<span class="absolute -top-[11px] left-1/2 -translate-x-1/2 rounded-full bg-trb17-acc px-3 py-[3px] text-[11px] font-bold tracking-[0.04em] whitespace-nowrap text-white">Recommended</span>
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Pro</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$19<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>Unlimited projects</li><li>Priority support</li><li>100 GB storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-line bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="team" class="sr-only">
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Team</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$49<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>Everything in Pro</li><li>SSO & audit log</li><li>Unlimited storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
</div>
<p class="mt-6 flex min-h-11 items-center gap-2.5 rounded-full bg-white px-5 text-sm text-trb17-body shadow-trb17-sum ring-1 ring-trb17-line">
<span aria-hidden="true" class="size-2 rounded-full bg-trb17-acc"></span>
<span class="hidden group-has-[[value=starter]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Starter</strong> — free forever, upgrade anytime.</span>
<span class="hidden group-has-[[value=pro]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Pro</strong> — 14-day free trial, cancel anytime.</span>
<span class="hidden group-has-[[value=team]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Team</strong> — includes onboarding for your whole org.</span>
</p>
</fieldset>
</section><section class="trb-17 w-full min-h-svh grid place-items-center bg-trb17-bg px-6 py-14 font-trb17-sans text-trb17-ink" aria-label="Subscription pricing plan cards demo">
<fieldset class="group/plans grid justify-items-center">
<legend class="text-center text-[28px] font-extrabold tracking-[-0.025em]">Pick your plan</legend>
<div class="mt-8 flex flex-wrap justify-center gap-[18px]">
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-line bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="starter" class="sr-only">
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Starter</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$0<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>3 projects</li><li>Community support</li><li>1 GB storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-acc/35 bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="pro" class="sr-only" checked>
<span class="absolute -top-[11px] left-1/2 -translate-x-1/2 rounded-full bg-trb17-acc px-3 py-[3px] text-[11px] font-bold tracking-[0.04em] whitespace-nowrap text-white">Recommended</span>
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Pro</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$19<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>Unlimited projects</li><li>Priority support</li><li>100 GB storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-line bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="team" class="sr-only">
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Team</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$49<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>Everything in Pro</li><li>SSO & audit log</li><li>Unlimited storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
</div>
<p class="mt-6 flex min-h-11 items-center gap-2.5 rounded-full bg-white px-5 text-sm text-trb17-body shadow-trb17-sum ring-1 ring-trb17-line">
<span aria-hidden="true" class="size-2 rounded-full bg-trb17-acc"></span>
<span class="hidden group-has-[[value=starter]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Starter</strong> — free forever, upgrade anytime.</span>
<span class="hidden group-has-[[value=pro]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Pro</strong> — 14-day free trial, cancel anytime.</span>
<span class="hidden group-has-[[value=team]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Team</strong> — includes onboarding for your whole org.</span>
</p>
</fieldset>
</section>@import "tailwindcss";
@theme {
--color-trb17-bg: #f4f5f9;
--color-trb17-bg: oklch(0.968 0.006 270);
--color-trb17-ink: #1c2130;
--color-trb17-ink: oklch(0.24 0.03 270);
--color-trb17-body: #4f5569;
--color-trb17-body: oklch(0.45 0.03 270);
--color-trb17-mut: #5f6579;
--color-trb17-mut: oklch(0.5 0.025 270);
--color-trb17-line: #e5e7f0;
--color-trb17-line: oklch(0.93 0.01 275);
--color-trb17-pill: #d7dae6;
--color-trb17-pill: oklch(0.89 0.015 275);
--color-trb17-acc: #3d5fe0;
--color-trb17-acc: oklch(0.55 0.2 262);
--shadow-trb17-lift: 0 22px 44px -20px oklch(0.55 0.2 262 / 0.55);
--shadow-trb17-sum: 0 8px 20px -14px oklch(0.25 0.03 270 / 0.25);
--font-trb17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.trb-17 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-trb17-bg: #f4f5f9;
--color-trb17-bg: oklch(0.968 0.006 270);
--color-trb17-ink: #1c2130;
--color-trb17-ink: oklch(0.24 0.03 270);
--color-trb17-body: #4f5569;
--color-trb17-body: oklch(0.45 0.03 270);
--color-trb17-mut: #5f6579;
--color-trb17-mut: oklch(0.5 0.025 270);
--color-trb17-line: #e5e7f0;
--color-trb17-line: oklch(0.93 0.01 275);
--color-trb17-pill: #d7dae6;
--color-trb17-pill: oklch(0.89 0.015 275);
--color-trb17-acc: #3d5fe0;
--color-trb17-acc: oklch(0.55 0.2 262);
--shadow-trb17-lift: 0 22px 44px -20px oklch(0.55 0.2 262 / 0.55);
--shadow-trb17-sum: 0 8px 20px -14px oklch(0.25 0.03 270 / 0.25);
--font-trb17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.trb-17 {
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-trb17-bg: #f4f5f9;
--color-trb17-bg: oklch(0.968 0.006 270);
--color-trb17-ink: #1c2130;
--color-trb17-ink: oklch(0.24 0.03 270);
--color-trb17-body: #4f5569;
--color-trb17-body: oklch(0.45 0.03 270);
--color-trb17-mut: #5f6579;
--color-trb17-mut: oklch(0.5 0.025 270);
--color-trb17-line: #e5e7f0;
--color-trb17-line: oklch(0.93 0.01 275);
--color-trb17-pill: #d7dae6;
--color-trb17-pill: oklch(0.89 0.015 275);
--color-trb17-acc: #3d5fe0;
--color-trb17-acc: oklch(0.55 0.2 262);
--shadow-trb17-lift: 0 22px 44px -20px oklch(0.55 0.2 262 / 0.55);
--shadow-trb17-sum: 0 8px 20px -14px oklch(0.25 0.03 270 / 0.25);
--font-trb17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.trb-17 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-trb17-bg: #f4f5f9;
--color-trb17-bg: oklch(0.968 0.006 270);
--color-trb17-ink: #1c2130;
--color-trb17-ink: oklch(0.24 0.03 270);
--color-trb17-body: #4f5569;
--color-trb17-body: oklch(0.45 0.03 270);
--color-trb17-mut: #5f6579;
--color-trb17-mut: oklch(0.5 0.025 270);
--color-trb17-line: #e5e7f0;
--color-trb17-line: oklch(0.93 0.01 275);
--color-trb17-pill: #d7dae6;
--color-trb17-pill: oklch(0.89 0.015 275);
--color-trb17-acc: #3d5fe0;
--color-trb17-acc: oklch(0.55 0.2 262);
--shadow-trb17-lift: 0 22px 44px -20px oklch(0.55 0.2 262 / 0.55);
--shadow-trb17-sum: 0 8px 20px -14px oklch(0.25 0.03 270 / 0.25);
--font-trb17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.trb-17 {
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..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=Plus+Jakarta+Sans:wght@400..800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The feature ticks moved from a
li::beforerule to child-and-pseudo stacked variants on the<ul>:*:before:border-l-2. .pill-idle,.pill-on{grid-area:1/1}became*:[grid-area:1/1]on the pill — one class for both children.- UI upgrade from the CSS original: the summary is now a pill with a status dot and bold plan name, and the pill hit area grew to 44px.
- UI upgrade: the lifts are
motion-safe:(never applied rather than undone), and feature copy rose from#5d6378to 7: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 Plan Radio Cards
Source: https://codefronts.com/components/tailwind-css-radio-buttons/tailwind-pricing-plan-radio-cards/
A complete pricing-table selector: three plan cards with price, features and a "Recommended" crown — each card a radio, so the whole table is one submittable form control. The Select / Selected ✓ pill is two spans stacked with [grid-area:1/1] and cross-faded by group-has-checked:; the summary line under the table follows the value.
## HTML
```html
<section class="trb-17 w-full min-h-svh grid place-items-center bg-trb17-bg px-6 py-14 font-trb17-sans text-trb17-ink" aria-label="Subscription pricing plan cards demo">
<fieldset class="group/plans grid justify-items-center">
<legend class="text-center text-[28px] font-extrabold tracking-[-0.025em]">Pick your plan</legend>
<div class="mt-8 flex flex-wrap justify-center gap-[18px]">
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-line bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="starter" class="sr-only">
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Starter</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$0<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>3 projects</li><li>Community support</li><li>1 GB storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-acc/35 bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="pro" class="sr-only" checked>
<span class="absolute -top-[11px] left-1/2 -translate-x-1/2 rounded-full bg-trb17-acc px-3 py-[3px] text-[11px] font-bold tracking-[0.04em] whitespace-nowrap text-white">Recommended</span>
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Pro</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$19<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>Unlimited projects</li><li>Priority support</li><li>100 GB storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-line bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="team" class="sr-only">
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Team</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$49<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>Everything in Pro</li><li>SSO & audit log</li><li>Unlimited storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
</div>
<p class="mt-6 flex min-h-11 items-center gap-2.5 rounded-full bg-white px-5 text-sm text-trb17-body shadow-trb17-sum ring-1 ring-trb17-line">
<span aria-hidden="true" class="size-2 rounded-full bg-trb17-acc"></span>
<span class="hidden group-has-[[value=starter]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Starter</strong> — free forever, upgrade anytime.</span>
<span class="hidden group-has-[[value=pro]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Pro</strong> — 14-day free trial, cancel anytime.</span>
<span class="hidden group-has-[[value=team]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Team</strong> — includes onboarding for your whole org.</span>
</p>
</fieldset>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-trb17-bg: #f4f5f9;
--color-trb17-bg: oklch(0.968 0.006 270);
--color-trb17-ink: #1c2130;
--color-trb17-ink: oklch(0.24 0.03 270);
--color-trb17-body: #4f5569;
--color-trb17-body: oklch(0.45 0.03 270);
--color-trb17-mut: #5f6579;
--color-trb17-mut: oklch(0.5 0.025 270);
--color-trb17-line: #e5e7f0;
--color-trb17-line: oklch(0.93 0.01 275);
--color-trb17-pill: #d7dae6;
--color-trb17-pill: oklch(0.89 0.015 275);
--color-trb17-acc: #3d5fe0;
--color-trb17-acc: oklch(0.55 0.2 262);
--shadow-trb17-lift: 0 22px 44px -20px oklch(0.55 0.2 262 / 0.55);
--shadow-trb17-sum: 0 8px 20px -14px oklch(0.25 0.03 270 / 0.25);
--font-trb17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.trb-17 {
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 Plan Radio Cards
Source: https://codefronts.com/components/tailwind-css-radio-buttons/tailwind-pricing-plan-radio-cards/
A complete pricing-table selector: three plan cards with price, features and a "Recommended" crown — each card a radio, so the whole table is one submittable form control. The Select / Selected ✓ pill is two spans stacked with [grid-area:1/1] and cross-faded by group-has-checked:; the summary line under the table follows the value.
## HTML
```html
<section class="trb-17 w-full min-h-svh grid place-items-center bg-trb17-bg px-6 py-14 font-trb17-sans text-trb17-ink" aria-label="Subscription pricing plan cards demo">
<fieldset class="group/plans grid justify-items-center">
<legend class="text-center text-[28px] font-extrabold tracking-[-0.025em]">Pick your plan</legend>
<div class="mt-8 flex flex-wrap justify-center gap-[18px]">
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-line bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="starter" class="sr-only">
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Starter</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$0<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>3 projects</li><li>Community support</li><li>1 GB storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-acc/35 bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="pro" class="sr-only" checked>
<span class="absolute -top-[11px] left-1/2 -translate-x-1/2 rounded-full bg-trb17-acc px-3 py-[3px] text-[11px] font-bold tracking-[0.04em] whitespace-nowrap text-white">Recommended</span>
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Pro</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$19<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>Unlimited projects</li><li>Priority support</li><li>100 GB storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
<label class="group relative grid w-[14.5rem] cursor-pointer content-start gap-1.5 rounded-[18px] border-2 border-trb17-line bg-white px-[22px] pt-7 pb-[22px] transition duration-250 hover:border-trb17-acc/45 has-checked:border-trb17-acc has-checked:shadow-trb17-lift has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-trb17-acc motion-safe:hover:-translate-y-0.5 motion-safe:has-checked:-translate-y-1 motion-reduce:transition-none">
<input type="radio" name="trb-17" value="team" class="sr-only">
<span class="text-sm font-bold tracking-[0.08em] text-trb17-mut uppercase">Team</span>
<span class="text-[34px] font-extrabold tracking-[-0.03em] tabular-nums">$49<small class="text-sm font-semibold tracking-normal text-trb17-mut">/mo</small></span>
<ul class="mt-2.5 grid gap-[7px] *:relative *:pl-5 *:text-[13.5px] *:text-trb17-body *:before:absolute *:before:top-[5px] *:before:left-0 *:before:h-1.5 *:before:w-2.5 *:before:-rotate-45 *:before:border-b-2 *:before:border-l-2 *:before:border-trb17-acc *:before:content-['']"><li>Everything in Pro</li><li>SSO & audit log</li><li>Unlimited storage</li></ul>
<span class="mt-[18px] grid min-h-11 place-items-center overflow-hidden rounded-[10px] border-[1.5px] border-trb17-pill text-sm font-bold text-trb17-body transition-colors duration-250 *:[grid-area:1/1] *:transition-[opacity,translate] *:duration-250 group-has-checked:border-trb17-acc group-has-checked:bg-trb17-acc"><span class="group-has-checked:-translate-y-1.5 group-has-checked:opacity-0">Select</span><span class="translate-y-1.5 text-white opacity-0 group-has-checked:translate-y-0 group-has-checked:opacity-100">Selected ✓</span></span>
</label>
</div>
<p class="mt-6 flex min-h-11 items-center gap-2.5 rounded-full bg-white px-5 text-sm text-trb17-body shadow-trb17-sum ring-1 ring-trb17-line">
<span aria-hidden="true" class="size-2 rounded-full bg-trb17-acc"></span>
<span class="hidden group-has-[[value=starter]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Starter</strong> — free forever, upgrade anytime.</span>
<span class="hidden group-has-[[value=pro]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Pro</strong> — 14-day free trial, cancel anytime.</span>
<span class="hidden group-has-[[value=team]:checked]/plans:inline"><strong class="font-bold text-trb17-ink">Team</strong> — includes onboarding for your whole org.</span>
</p>
</fieldset>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-trb17-bg: #f4f5f9;
--color-trb17-bg: oklch(0.968 0.006 270);
--color-trb17-ink: #1c2130;
--color-trb17-ink: oklch(0.24 0.03 270);
--color-trb17-body: #4f5569;
--color-trb17-body: oklch(0.45 0.03 270);
--color-trb17-mut: #5f6579;
--color-trb17-mut: oklch(0.5 0.025 270);
--color-trb17-line: #e5e7f0;
--color-trb17-line: oklch(0.93 0.01 275);
--color-trb17-pill: #d7dae6;
--color-trb17-pill: oklch(0.89 0.015 275);
--color-trb17-acc: #3d5fe0;
--color-trb17-acc: oklch(0.55 0.2 262);
--shadow-trb17-lift: 0 22px 44px -20px oklch(0.55 0.2 262 / 0.55);
--shadow-trb17-sum: 0 8px 20px -14px oklch(0.25 0.03 270 / 0.25);
--font-trb17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.trb-17 {
width: 100%;
min-height: 100svh;
}
```How this works
Stacking without absolute. *:[grid-area:1/1] on the pill puts both spans into the same grid cell, so the pill sizes to the longer label and the cross-fade never jumps.
The recommended tier is just different classes. Its crown is a real span and it rests with a tinted border; selection styling layers on top through the same has-checked: variants as its siblings.
Make it yours
- Move the recommendation: move the crown span and the tinted resting border.
- Accent:
--color-trb17-accdrives border, pill, ticks and shadow. - Localise the pill: both states are plain text.
Gotchas — read before shipping
- Feature lists inside labels are read in full — keep them to 3–4 items.
- The pill is a span, not a button — the label is the control; never nest a real button.
- Reserve the border width at rest so the checked swap doesn't shift layout.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
:has() drives card state, pill swap and summary; cards still select natively without it.