Browser default radio buttons look terrible. They clash with modern designs and render differently across Chrome, Firefox, and Safari.
These Tailwind radio button examples show you how to build consistent, accessible selection controls using utility-first classes.
You will find patterns for basic radios, inline groups, card-style selectors, custom styled inputs, and dark mode variants.
Each example includes copy-ready code that works with the Tailwind CSS framework out of the box.
Whether you are building a Tailwind modal with form controls or a complete checkout flow, these patterns cover real production scenarios.
What is a Tailwind Radio Button
A Tailwind radio button is a form input element styled using Tailwind CSS utility classes.
It lets users select a single option from a group of choices.
Unlike CSS checkboxes that allow multiple selections, radio buttons enforce mutually exclusive choices within a named group.
The input type radio element works natively in HTML, but browser default styling looks outdated and inconsistent across platforms.
Tailwind solves this with utility-first CSS classes that give you full control over appearance, spacing, and states.
Tailwind radio button examples
Tailwind CSS Radio Button – Flowbite

Tailwind CSS Radio Button

Radio Buttons By hafizhaziq.dev

Tailwind CSS Radio Button Cards

Tailwind CSS Radio Button – Preline

Tailwind CSS Toggle Checkbox Radio Component

Radio Button Images Demo by David Bradbury

Tailwind CSS Radio- Material Tailwind

Tailwind CSS Custom Radio Button

Radio Magic with Tailwind

Animated Choices

Reacting with Tailwind

Styling with a Twist

Jim’s Radio Revolution

Sail the UI Waves with Tailwind

Tune into Componentland

Push My Buttons with Tailwind

Keep It Simple, Keep It Radio

Svelte’s Radio Groove

Aston’s Gender Bender Buttons

How Do Tailwind Radio Buttons Work
Radio buttons in Tailwind combine standard HTML input elements with utility classes for styling.
The peer selector connects the input to its label, enabling custom checked state designs.
When a user clicks any radio button in a group, the browser automatically deselects the previously checked option.
All radios sharing the same name attribute belong to one selection group.
Tailwind’s approach keeps the native input functional for accessible forms while completely transforming the visual presentation.
Screen readers and keyboard navigation work exactly as expected because the underlying HTML structure stays standard.
What CSS Classes Style Tailwind Radio Buttons
Tailwind provides specific utility classes for form control styling, appearance modification, and state management.
Which Utility Classes Control Radio Button Appearance
The appearance-none class removes default browser styling, giving you a blank canvas.
Use rounded-full for circular shape, border for outline, and checked:bg-blue-500 for the selected state color.
The accent-color property offers a simpler alternative when you want minimal customization.
Which Classes Handle Radio Button Spacing
Apply gap-2 or space-x-2 between the radio and its label text.
For radio groups, space-y-3 creates vertical separation between options, while flex with gap-4 handles inline layouts.
Basic Tailwind Radio Button Example
This example shows a minimal radio button with Tailwind utility classes applied to a standard Tailwind input element.
“ <div class="flex items-center"> <input type="radio" id="option1" name="basic" class="w-4 h-4 text-blue-600 border-gray-300 focus:ring-blue-500" > <label for="option1" class="ml-2 text-sm text-gray-700"> Option One </label> </div> `
The w-4 h-4 classes set a 16px size.
text-blue-600 colors the checked state, and focus:ring-blue-500 adds keyboard focus indication.
This pattern works across Chrome, Firefox, Safari, and Edge with consistent results.
Tailwind Radio Button with Label Example
Proper label association improves user experience and accessibility by expanding the clickable area.
` <fieldset class="space-y-3"> <legend class="text-sm font-medium text-gray-900">Select plan</legend>
<div class=”flex items-center”> <input type=”radio” id=”free” name=”plan” value=”free” class=”w-4 h-4 text-indigo-600 border-gray-300 focus:ring-indigo-500″ > <label for=”free” class=”ml-3 text-sm text-gray-700″> Free tier </label> </div>
<div class=”flex items-center”> <input type=”radio” id=”pro” name=”plan” value=”pro” class=”w-4 h-4 text-indigo-600 border-gray-300 focus:ring-indigo-500″ > <label for=”pro” class=”ml-3 text-sm text-gray-700″> Pro plan </label> </div> </fieldset> `
The fieldset and legend elements group related radios semantically.
Each for attribute on the label matches the corresponding input id, creating the association.
This structure passes WCAG accessibility requirements and integrates well with Tailwind forms plugins.
Tailwind Inline Radio Button Group Example
Inline radio groups display options horizontally, saving vertical space on landing pages and compact forms.
` <div class="flex items-center gap-6"> <div class="flex items-center"> <input type="radio" id="small" name="size" value="small" class="w-4 h-4 text-blue-600 border-gray-300 focus:ring-blue-500"> <label for="small" class="ml-2 text-sm text-gray-700">Small</label> </div>
<div class=”flex items-center”> <input type=”radio” id=”medium” name=”size” value=”medium” class=”w-4 h-4 text-blue-600 border-gray-300 focus:ring-blue-500″> <label for=”medium” class=”ml-2 text-sm text-gray-700″>Medium</label> </div>
<div class=”flex items-center”> <input type=”radio” id=”large” name=”size” value=”large” class=”w-4 h-4 text-blue-600 border-gray-300 focus:ring-blue-500″> <label for=”large” class=”ml-2 text-sm text-gray-700″>Large</label> </div> </div> `
The parent flex container with gap-6 spaces each option evenly.
Works best for 3-5 short options. More than that, switch to stacked layout.
Tailwind Stacked Radio Button Group Example
Stacked layouts work better for longer option labels and mobile viewport sizes.
` <div class="space-y-4"> <div class="flex items-center"> <input type="radio" id="email" name="contact" value="email" class="w-4 h-4 text-emerald-600 border-gray-300 focus:ring-emerald-500"> <label for="email" class="ml-3 text-sm text-gray-900"> Email notifications </label> </div>
<div class=”flex items-center”> <input type=”radio” id=”sms” name=”contact” value=”sms” class=”w-4 h-4 text-emerald-600 border-gray-300 focus:ring-emerald-500″> <label for=”sms” class=”ml-3 text-sm text-gray-900″> SMS notifications </label> </div>
<div class=”flex items-center”> <input type=”radio” id=”none” name=”contact” value=”none” class=”w-4 h-4 text-emerald-600 border-gray-300 focus:ring-emerald-500″> <label for=”none” class=”ml-3 text-sm text-gray-900″> No notifications </label> </div> </div> `
The space-y-4 class adds consistent vertical gaps between options.
This pattern scales well regardless of how many choices you add.
Tailwind Radio Button with Description Text Example
Adding description text helps users understand each option without external documentation.
` <div class="space-y-4"> <div class="flex items-start"> <input type="radio" id="starter" name="pricing" value="starter" class="mt-1 w-4 h-4 text-violet-600 border-gray-300 focus:ring-violet-500"> <div class="ml-3"> <label for="starter" class="text-sm font-medium text-gray-900"> Starter </label> <p class="text-sm text-gray-500">Best for personal projects</p> </div> </div>
<div class=”flex items-start”> <input type=”radio” id=”business” name=”pricing” value=”business” class=”mt-1 w-4 h-4 text-violet-600 border-gray-300 focus:ring-violet-500″> <div class=”ml-3″> <label for=”business” class=”text-sm font-medium text-gray-900″> Business </label> <p class=”text-sm text-gray-500″>For teams up to 20 members</p> </div> </div> </div> `
Switch from items-center to items-start so the radio aligns with the label top.
The mt-1 on the input fine-tunes vertical alignment with the text baseline.
Tailwind Radio Button Card Example
Card-style radios create a stronger visual hierarchy for high-stakes choices like payment methods or subscription tiers.
` <div class="grid gap-4 sm:grid-cols-2"> <label class="relative flex cursor-pointer rounded-lg border p-4 focus-within:ring-2 focus-within:ring-blue-500 hover:bg-gray-50"> <input type="radio" name="card" value="monthly" class="sr-only peer"> <div class="flex flex-1 flex-col"> <span class="text-sm font-medium text-gray-900">Monthly</span> <span class="mt-1 text-sm text-gray-500">$12/month</span> </div> <div class="h-5 w-5 rounded-full border flex items-center justify-center peer-checked:border-blue-600 peer-checked:bg-blue-600"> <div class="h-2 w-2 rounded-full bg-white opacity-0 peer-checked:opacity-100"></div> </div> </label>
<label class=”relative flex cursor-pointer rounded-lg border p-4 focus-within:ring-2 focus-within:ring-blue-500 hover:bg-gray-50″> <input type=”radio” name=”card” value=”annual” class=”sr-only peer”> <div class=”flex flex-1 flex-col”> <span class=”text-sm font-medium text-gray-900″>Annual</span> <span class=”mt-1 text-sm text-gray-500″>$99/year</span> </div> <div class=”h-5 w-5 rounded-full border flex items-center justify-center peer-checked:border-blue-600 peer-checked:bg-blue-600″> <div class=”h-2 w-2 rounded-full bg-white opacity-0 peer-checked:opacity-100″></div> </div> </label> </div> `
The sr-only class hides the native input while keeping it accessible to screen readers.
Peer modifiers like peer-checked:bg-blue-600 style sibling elements based on input state.
Tailwind Custom Styled Radio Button Example
Full custom styling replaces the browser default entirely with your own design.
` <label class="flex items-center cursor-pointer"> <div class="relative"> <input type="radio" name="custom" value="one" class="sr-only peer"> <div class="w-6 h-6 rounded-full border-2 border-gray-300 peer-checked:border-indigo-600 transition-colors"></div> <div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-3 h-3 rounded-full bg-indigo-600 scale-0 peer-checked:scale-100 transition-transform"></div> </div> <span class="ml-3 text-sm text-gray-700">Custom option</span> </label> `
Two stacked divs create the outer ring and inner dot.
The scale-0 to scale-100 CSS animation transition makes the checked state feel smooth.
Tailwind Radio Button with Icon Example
Icons help users scan options faster, especially for visual concepts like payment methods or shipping speeds.
` <div class="space-y-3"> <label class="flex items-center p-3 border rounded-lg cursor-pointer hover:bg-gray-50 has-[:checked]:border-blue-500 has-[:checked]:bg-blue-50"> <input type="radio" name="shipping" value="standard" class="w-4 h-4 text-blue-600"> <svg class="ml-3 w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"/> </svg> <div class="ml-3"> <span class="text-sm font-medium text-gray-900">Standard</span> <span class="text-sm text-gray-500 ml-2">4-7 days</span> </div> </label> </div> `
Inline SVG icons stay crisp at any size and inherit text color through currentColor.
The has-[:checked] selector styles the parent container when the radio is selected.
Tailwind Disabled Radio Button Example
Disabled states communicate unavailable options without removing them from the user interface.
` <div class="flex items-center"> <input type="radio" id="unavailable" name="status" value="unavailable" disabled class="w-4 h-4 text-gray-400 border-gray-200 cursor-not-allowed"> <label for="unavailable" class="ml-2 text-sm text-gray-400 cursor-not-allowed"> Currently unavailable </label> </div> `
The disabled attribute prevents interaction.
Match text-gray-400 on both input and label, add cursor-not-allowed for visual feedback.
Tailwind Radio Button with Validation Example
Validation states show users when their selection is required or contains an error.
` <fieldset class="space-y-3"> <legend class="text-sm font-medium text-gray-900"> Select an option <span class="text-red-500">*</span> </legend>
<div class=”flex items-center”> <input type=”radio” id=”valid1″ name=”validate” value=”one” required class=”w-4 h-4 text-blue-600 border-gray-300 invalid:border-red-500 focus:ring-blue-500″> <label for=”valid1″ class=”ml-2 text-sm text-gray-700″>Option A</label> </div>
<div class=”flex items-center”> <input type=”radio” id=”valid2″ name=”validate” value=”two” class=”w-4 h-4 text-blue-600 border-gray-300 focus:ring-blue-500″> <label for=”valid2″ class=”ml-2 text-sm text-gray-700″>Option B</label> </div>
<p class=”text-sm text-red-600 hidden peer-invalid:block”> Please select an option </p> </fieldset> `
The required attribute triggers browser validation on form submission.
Use invalid:border-red-500 to style the error state, pair with a descriptive error message.
Tailwind Dark Mode Radio Button Example
Dark mode support requires explicit color classes for backgrounds, borders, and text.
` <div class="p-4 bg-white dark:bg-gray-800 rounded-lg"> <div class="flex items-center"> <input type="radio" id="dark1" name="darkmode" value="light" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600 focus:ring-blue-500"> <label for="dark1" class="ml-2 text-sm text-gray-900 dark:text-gray-100"> Light theme </label> </div>
<div class=”flex items-center mt-3″> <input type=”radio” id=”dark2″ name=”darkmode” value=”dark” class=”w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600 focus:ring-blue-500″> <label for=”dark2″ class=”ml-2 text-sm text-gray-900 dark:text-gray-100″> Dark theme </label> </div> </div> `
The dark: prefix applies styles when dark mode is active.
Test both modes to ensure sufficient color contrast ratios meet web accessibility standards.
Which Tailwind Radio Button Style Fits Different Use Cases
Picking the right pattern depends on context, option count, and how much information each choice needs.
- Basic/labeled radios – simple settings, filters, short surveys
- Inline groups – 3-5 short options, size selectors, yes/no questions
- Stacked groups – longer labels, mobile forms, 5+ options
- Description radios – pricing tiers, feature comparisons, onboarding flows
- Card radios – payment methods, subscription plans, high-value decisions
- Icon radios – shipping options, notification preferences, visual categories
Card and icon styles require more markup but create stronger interactive elements that improve conversion rates.
Basic radios load faster and work reliably with JavaScript frameworks like React or Vue.
FAQ on Tailwind Radio Button Examples
How do I style a radio button in Tailwind CSS?
Apply utility classes directly to the input element. Use w-4 h-4 for size, text-blue-600 for checked color, and focus:ring-blue-500 for focus states. The appearance-none class removes browser defaults when building custom radio designs.
How do I create a radio button group in Tailwind?
Wrap multiple radio inputs sharing the same name attribute inside a container. Use space-y-3 for vertical spacing or flex gap-4 for inline layouts. The shared name attribute ensures only one option stays selected.
How do I make Tailwind radio buttons accessible?
Always associate labels with inputs using matching for and id attributes. Add focus:ring classes for keyboard navigation visibility. Use fieldset and legend elements to group related options, following ARIA best practices.
Can I use Tailwind radio buttons with React?
Yes. Tailwind utility classes work with React components without modification. Manage the checked state through React’s useState hook. Libraries like Headless UI provide pre-built accessible radio group components styled with Tailwind classes.
How do I style the checked state of a Tailwind radio button?
Use the checked: modifier prefix. Apply checked:bg-blue-600 for background color or checked:border-blue-600 for borders. For custom designs, combine peer class on inputs with peer-checked: modifiers on sibling elements.
How do I disable a radio button in Tailwind?
Add the disabled HTML attribute to the input. Style with disabled:opacity-50 and disabled:cursor-not-allowed classes. Match the label styling with text-gray-400 to visually communicate the unavailable state to users.
How do I add validation to Tailwind radio buttons?
Add the required attribute to at least one radio in the group. Use invalid:border-red-500 for error styling. Display error messages conditionally with frontend JavaScript or form validation libraries.
How do I create card-style radio buttons in Tailwind?
Hide the native input with sr-only class. Wrap content in a styled label with border, padding, and CSS hover effects. Use peer-checked: modifiers to change card appearance when selected.
Do Tailwind radio buttons work in dark mode?
Yes. Add dark: prefixed classes for dark mode variants. Use dark:bg-gray-700 for backgrounds and dark:border-gray-600 for borders. Test contrast ratios in both modes to maintain readability and usability.
How do I align radio buttons with multi-line labels?
Switch from items-center to items-start on the flex container. Add mt-1 to the input element to align it with the first line of text. This keeps the radio visually anchored to the label top.
Conclusion
These Tailwind radio button examples give you production-ready patterns for any form scenario.
From basic input groups to card-style selectors, each pattern uses the same utility class approach that makes Tailwind CSS predictable.
The peer selector and checked state modifiers handle interactivity without custom responsive design breakpoints or extra stylesheets.
Focus rings and proper label associations keep your radio buttons keyboard accessible out of the box.
Pair these radio patterns with Tailwind buttons and Tailwind cards to build complete form interfaces.
Test across devices. The flex and gap utilities adapt cleanly to mobile-first design without media query overrides.
Copy the code, adjust the colors, ship it.
