Tailwind CSS and Alpine JS Radio
Radio buttons allow users to select one option from a list of options.
Default radio
A radio button with a label. This component uses before pseudo-element instead of the browser's default radio button dot indicator. It makes the code slightly more complex, but it provides the luxury of customizing the style of the radio button.
Classic vs Modern Code Style
The difference between the two versions is how they're written. The classic version uses older-style classes like 'text-red-500' for styling, while the modern version, uses CSS variables and semantic names like 'text-primary' for theming. It's important to note that 'Classic' doesn't mean an older version—they both use Tailwind V4. Tell me more.
<div class="">
<div class="">
<input id="radioMac" type="radio" class="" name="radioDefault" value="" checked >
<label for="radioMac" class="">Mac</label>
</div>
<div class="">
<input id="radioWindows" type="radio" class="" name="radioDefault" value="">
<label for="radioWindows" class="">Windows</label>
</div>
<div class="">
<input id="radioLinux" type="radio" class="" name="radioDefault" value="">
<label for="radioLinux" class="">Linux</label>
</div>
</div>
<div class="">
<div class="">
<input id="radioMac" type="radio" class="" name="radioDefault" value="" checked >
<label for="radioMac" class="">Mac</label>
</div>
<div class="">
<input id="radioWindows" type="radio" class="" name="radioDefault" value="">
<label for="radioWindows" class="">Windows</label>
</div>
<div class="">
<input id="radioLinux" type="radio" class="" name="radioDefault" value="">
<label for="radioLinux" class="">Linux</label>
</div>
</div>
@theme {
/* light theme */
--color-surface: var(--color-);
--color-surface-alt: var(--color-);
--color-on-surface: var(--color-);
--color-on-surface-strong: var(--color-);
--color-primary: var(--color-);
--color-on-primary: var(--color-);
--color-secondary: var(--color-);
--color-on-secondary: var(--color-);
--color-outline: ;
--color-outline-strong: var(--color-);
/* dark theme */
--color-surface-dark: var(--color-);
--color-surface-dark-alt: var(--color-);
--color-on-surface-dark: var(--color-);
--color-on-surface-dark-strong: var(--color-);
--color-primary-dark: var(--color-);
--color-on-primary-dark: var(--color-);
--color-secondary-dark: var(--color-);
--color-on-secondary-dark: var(--color-);
--color-outline-dark: var(--color-);
--color-outline-dark-strong: var(--color-);
/* shared colors */
--color-info: var(--color-);
--color-on-info: var(--color-);
--color-success: var(--color-);
--color-on-success: var(--color-);
--color-warning: var(--color-);
--color-on-warning: var(--color-);
--color-danger: var(--color-);
--color-on-danger: var(--color-);
/* border radius */
--radius-radius: var(--radius);
}
Radio with container
A radio button with a contrasting background and label that makes it easy to find and interact with it.
Classic vs Modern Code Style
The difference between the two versions is how they're written. The classic version uses older-style classes like 'text-red-500' for styling, while the modern version, uses CSS variables and semantic names like 'text-primary' for theming. It's important to note that 'Classic' doesn't mean an older version—they both use Tailwind V4. Tell me more.
<div class="">
<label for="radioMac" class="">
<input id="radioMac" type="radio" class="" name="radioDefault" value="" checked >
<span class="">Mac</span>
</label>
<label for="radioWindows" class="">
<input id="radioWindows" type="radio" class="" name="radioDefault" value="">
<span class="">Windows</span>
</label>
<label for="radioLinux" class="">
<input id="radioLinux" type="radio" class="" name="radioDefault" value="">
<span class="">Linux</span>
</label>
</div>
<div class="">
<label for="radioMac" class="">
<input id="radioMac" type="radio" class="" name="radioDefault" value="" checked >
<span class="">Mac</span>
</label>
<label for="radioWindows" class="">
<input id="radioWindows" type="radio" class="" name="radioDefault" value="">
<span class="">Windows</span>
</label>
<label for="radioLinux" class="">
<input id="radioLinux" type="radio" class="" name="radioDefault" value="">
<span class="">Linux</span>
</label>
</div>
@theme {
/* light theme */
--color-surface: var(--color-);
--color-surface-alt: var(--color-);
--color-on-surface: var(--color-);
--color-on-surface-strong: var(--color-);
--color-primary: var(--color-);
--color-on-primary: var(--color-);
--color-secondary: var(--color-);
--color-on-secondary: var(--color-);
--color-outline: ;
--color-outline-strong: var(--color-);
/* dark theme */
--color-surface-dark: var(--color-);
--color-surface-dark-alt: var(--color-);
--color-on-surface-dark: var(--color-);
--color-on-surface-dark-strong: var(--color-);
--color-primary-dark: var(--color-);
--color-on-primary-dark: var(--color-);
--color-secondary-dark: var(--color-);
--color-on-secondary-dark: var(--color-);
--color-outline-dark: var(--color-);
--color-outline-dark-strong: var(--color-);
/* shared colors */
--color-info: var(--color-);
--color-on-info: var(--color-);
--color-success: var(--color-);
--color-on-success: var(--color-);
--color-warning: var(--color-);
--color-on-warning: var(--color-);
--color-danger: var(--color-);
--color-on-danger: var(--color-);
/* border radius */
--radius-radius: var(--radius);
}
Radio with description
A radio button with a label and description.
Classic vs Modern Code Style
The difference between the two versions is how they're written. The classic version uses older-style classes like 'text-red-500' for styling, while the modern version, uses CSS variables and semantic names like 'text-primary' for theming. It's important to note that 'Classic' doesn't mean an older version—they both use Tailwind V4. Tell me more.
<div class="">
<div class="">
<input id="radioMac" type="radio" class="" name="radioDefault" value="" aria-describedby="radioMacDescription" checked >
<label for="radioMac" class="">Mac</label>
</div>
<span id="radioMacDescription" class="">For macOS Big Sur and higher</span>
</div>
<div class="">
<div class="">
<input id="radioMac" type="radio" class="" name="radioDefault" value="" aria-describedby="radioMacDescription" checked >
<label for="radioMac" class="">Mac</label>
</div>
<span id="radioMacDescription" class="">For macOS Big Sur and higher</span>
</div>
@theme {
/* light theme */
--color-surface: var(--color-);
--color-surface-alt: var(--color-);
--color-on-surface: var(--color-);
--color-on-surface-strong: var(--color-);
--color-primary: var(--color-);
--color-on-primary: var(--color-);
--color-secondary: var(--color-);
--color-on-secondary: var(--color-);
--color-outline: ;
--color-outline-strong: var(--color-);
/* dark theme */
--color-surface-dark: var(--color-);
--color-surface-dark-alt: var(--color-);
--color-on-surface-dark: var(--color-);
--color-on-surface-dark-strong: var(--color-);
--color-primary-dark: var(--color-);
--color-on-primary-dark: var(--color-);
--color-secondary-dark: var(--color-);
--color-on-secondary-dark: var(--color-);
--color-outline-dark: var(--color-);
--color-outline-dark-strong: var(--color-);
/* shared colors */
--color-info: var(--color-);
--color-on-info: var(--color-);
--color-success: var(--color-);
--color-on-success: var(--color-);
--color-warning: var(--color-);
--color-on-warning: var(--color-);
--color-danger: var(--color-);
--color-on-danger: var(--color-);
/* border radius */
--radius-radius: var(--radius);
}
Radio color variants
A radio button with a label and description in various colors.
Classic vs Modern Code Style
The difference between the two versions is how they're written. The classic version uses older-style classes like 'text-red-500' for styling, while the modern version, uses CSS variables and semantic names like 'text-primary' for theming. It's important to note that 'Classic' doesn't mean an older version—they both use Tailwind V4. Tell me more.
<!-- primary Radio -->
<div class="">
<input id="radioPrimary" type="radio" class="" value="" checked >
<label for="radioPrimary" class="">Primary</label>
</div>
<!-- secondary Radio -->
<div class="">
<input id="radioSecondary" type="radio" class="" value="" checked >
<label for="radioSecondary" class="">Secondary</label>
</div>
<!-- success Radio -->
<div class="">
<input id="radioSuccess" type="radio" class="" value="" checked >
<label for="radioSuccess" class="">Success</label>
</div>
<!-- info Radio -->
<div class="">
<input id="radioInfo" type="radio" class="" value="" checked >
<label for="radioInfo" class="">Info</label>
</div>
<!-- warning Radio -->
<div class="">
<input id="radioWarning" type="radio" class="" value="" checked >
<label for="radioWarning" class="">Warning</label>
</div>
<!-- danger Radio -->
<div class="">
<input id="radioDanger" type="radio" class="" value="" checked >
<label for="radioDanger" class="">Danger</label>
</div>
<!-- primary Radio -->
<div class="">
<input id="radioPrimary" type="radio" class="" value="" checked >
<label for="radioPrimary" class="">Primary</label>
</div>
<!-- secondary Radio -->
<div class="">
<input id="radioSecondary" type="radio" class="" value="" checked >
<label for="radioSecondary" class="">Secondary</label>
</div>
<!-- success Radio -->
<div class="">
<input id="radioSuccess" type="radio" class="" value="" checked >
<label for="radioSuccess" class="">Success</label>
</div>
<!-- info Radio -->
<div class="">
<input id="radioInfo" type="radio" class="" value="" checked >
<label for="radioInfo" class="">Info</label>
</div>
<!-- warning Radio -->
<div class="">
<input id="radioWarning" type="radio" class="" value="" checked >
<label for="radioWarning" class="">Warning</label>
</div>
<!-- danger Radio -->
<div class="">
<input id="radioDanger" type="radio" class="" value="" checked >
<label for="radioDanger" class="">Danger</label>
</div>
@theme {
/* light theme */
--color-surface: var(--color-);
--color-surface-alt: var(--color-);
--color-on-surface: var(--color-);
--color-on-surface-strong: var(--color-);
--color-primary: var(--color-);
--color-on-primary: var(--color-);
--color-secondary: var(--color-);
--color-on-secondary: var(--color-);
--color-outline: ;
--color-outline-strong: var(--color-);
/* dark theme */
--color-surface-dark: var(--color-);
--color-surface-dark-alt: var(--color-);
--color-on-surface-dark: var(--color-);
--color-on-surface-dark-strong: var(--color-);
--color-primary-dark: var(--color-);
--color-on-primary-dark: var(--color-);
--color-secondary-dark: var(--color-);
--color-on-secondary-dark: var(--color-);
--color-outline-dark: var(--color-);
--color-outline-dark-strong: var(--color-);
/* shared colors */
--color-info: var(--color-);
--color-on-info: var(--color-);
--color-success: var(--color-);
--color-on-success: var(--color-);
--color-warning: var(--color-);
--color-on-warning: var(--color-);
--color-danger: var(--color-);
--color-on-danger: var(--color-);
/* border radius */
--radius-radius: var(--radius);
}
Custom radio
Examples of cards as radio buttons.
Classic vs Modern Code Style
The difference between the two versions is how they're written. The classic version uses older-style classes like 'text-red-500' for styling, while the modern version, uses CSS variables and semantic names like 'text-primary' for theming. It's important to note that 'Classic' doesn't mean an older version—they both use Tailwind V4. Tell me more.
<div class="">
<!-- Mac -->
<label class="">
<input type="radio" id="osMac" aria-describedby="macDescription" class="" name="os" value="mac" checked >
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 16 16" fill="currentColor" class="">
<path fill-rule="evenodd" d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd">
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="" viewBox="0 0 16 16">
<path d="M11.182.008C11.148-.03 9.923.023 8.857 1.18c-1.066 1.156-.902 2.482-.878 2.516s1.52.087 2.475-1.258.762-2.391.728-2.43m3.314 11.733c-.048-.096-2.325-1.234-2.113-3.422s1.675-2.789 1.698-2.854-.597-.79-1.254-1.157a3.7 3.7 0 0 0-1.563-.434c-.108-.003-.483-.095-1.254.116-.508.139-1.653.589-1.968.607-.316.018-1.256-.522-2.267-.665-.647-.125-1.333.131-1.824.328-.49.196-1.422.754-2.074 2.237-.652 1.482-.311 3.83-.067 4.56s.625 1.924 1.273 2.796c.576.984 1.34 1.667 1.659 1.899s1.219.386 1.843.067c.502-.308 1.408-.485 1.766-.472.357.013 1.061.154 1.782.539.571.197 1.111.115 1.652-.105.541-.221 1.324-1.059 2.238-2.758q.52-1.185.473-1.282">
</svg>
<div class="">
<h3 class="" aria-hidden="true">Mac</h3>
<small id="macDescription">MacOS Catalina and higher</small>
</div>
</label>
<!-- Windows -->
<label class="">
<input type="radio" id="osWindows" aria-describedby="windowsDescription" class="" name="os" value="windows">
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 16 16" fill="currentColor" class="">
<path fill-rule="evenodd" d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd">
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="" viewBox="0 0 16 16">
<path d="M6.555 1.375 0 2.237v5.45h6.555zM0 13.795l6.555.933V8.313H0zm7.278-5.4.026 6.378L16 16V8.395zM16 0 7.33 1.244v6.414H16z">
</svg>
<div class="">
<h3 class="" aria-hidden="true">Windows</h3>
<small id="windowsDescription">Windows 10 and higher</small>
</div>
</label>
<!-- Linux -->
<label class="">
<input type="radio" id="osLinux" aria-describedby="linuxDescription" class="" name="os" value="linux">
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 16 16" fill="currentColor" class="">
<path fill-rule="evenodd" d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd">
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="" viewBox="0 0 16 16">
<path d="M2.273 9.53a2.273 2.273 0 1 0 0-4.546 2.273 2.273 0 0 0 0 4.547Zm9.467-4.984a2.273 2.273 0 1 0 0-4.546 2.273 2.273 0 0 0 0 4.546M7.4 13.108a5.54 5.54 0 0 1-3.775-2.88 3.27 3.27 0 0 1-1.944.24 7.4 7.4 0 0 0 5.328 4.465c.53.113 1.072.169 1.614.166a3.25 3.25 0 0 1-.666-1.9 6 6 0 0 1-.557-.091m3.828 2.285a2.273 2.273 0 1 0 0-4.546 2.273 2.273 0 0 0 0 4.546m3.163-3.108a7.44 7.44 0 0 0 .373-8.726 3.3 3.3 0 0 1-1.278 1.498 5.57 5.57 0 0 1-.183 5.535 3.26 3.26 0 0 1 1.088 1.693M2.098 3.998a3.3 3.3 0 0 1 1.897.486 5.54 5.54 0 0 1 4.464-2.388c.037-.67.277-1.313.69-1.843a7.47 7.47 0 0 0-7.051 3.745">
</svg>
<div class="">
<h3 class="" aria-hidden="true">Linux</h3>
<small id="linuxDescription">Ubuntu 20.04 and higher</small>
</div>
</label>
</div>
<div class="">
<!-- Mac -->
<label class="">
<input type="radio" id="osMac" aria-describedby="macDescription" class="" name="os" value="mac" checked >
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 16 16" fill="currentColor" class="">
<path fill-rule="evenodd" d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd">
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="" viewBox="0 0 16 16">
<path d="M11.182.008C11.148-.03 9.923.023 8.857 1.18c-1.066 1.156-.902 2.482-.878 2.516s1.52.087 2.475-1.258.762-2.391.728-2.43m3.314 11.733c-.048-.096-2.325-1.234-2.113-3.422s1.675-2.789 1.698-2.854-.597-.79-1.254-1.157a3.7 3.7 0 0 0-1.563-.434c-.108-.003-.483-.095-1.254.116-.508.139-1.653.589-1.968.607-.316.018-1.256-.522-2.267-.665-.647-.125-1.333.131-1.824.328-.49.196-1.422.754-2.074 2.237-.652 1.482-.311 3.83-.067 4.56s.625 1.924 1.273 2.796c.576.984 1.34 1.667 1.659 1.899s1.219.386 1.843.067c.502-.308 1.408-.485 1.766-.472.357.013 1.061.154 1.782.539.571.197 1.111.115 1.652-.105.541-.221 1.324-1.059 2.238-2.758q.52-1.185.473-1.282">
</svg>
<div class="">
<h3 class="" aria-hidden="true">Mac</h3>
<small id="macDescription">MacOS Catalina and higher</small>
</div>
</label>
<!-- Windows -->
<label class="">
<input type="radio" id="osWindows" aria-describedby="windowsDescription" class="" name="os" value="windows">
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 16 16" fill="currentColor" class="">
<path fill-rule="evenodd" d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd">
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="" viewBox="0 0 16 16">
<path d="M6.555 1.375 0 2.237v5.45h6.555zM0 13.795l6.555.933V8.313H0zm7.278-5.4.026 6.378L16 16V8.395zM16 0 7.33 1.244v6.414H16z">
</svg>
<div class="">
<h3 class="" aria-hidden="true">Windows</h3>
<small id="windowsDescription">Windows 10 and higher</small>
</div>
</label>
<!-- Linux -->
<label class="">
<input type="radio" id="osLinux" aria-describedby="linuxDescription" class="" name="os" value="linux">
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 16 16" fill="currentColor" class="">
<path fill-rule="evenodd" d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd">
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="" viewBox="0 0 16 16">
<path d="M2.273 9.53a2.273 2.273 0 1 0 0-4.546 2.273 2.273 0 0 0 0 4.547Zm9.467-4.984a2.273 2.273 0 1 0 0-4.546 2.273 2.273 0 0 0 0 4.546M7.4 13.108a5.54 5.54 0 0 1-3.775-2.88 3.27 3.27 0 0 1-1.944.24 7.4 7.4 0 0 0 5.328 4.465c.53.113 1.072.169 1.614.166a3.25 3.25 0 0 1-.666-1.9 6 6 0 0 1-.557-.091m3.828 2.285a2.273 2.273 0 1 0 0-4.546 2.273 2.273 0 0 0 0 4.546m3.163-3.108a7.44 7.44 0 0 0 .373-8.726 3.3 3.3 0 0 1-1.278 1.498 5.57 5.57 0 0 1-.183 5.535 3.26 3.26 0 0 1 1.088 1.693M2.098 3.998a3.3 3.3 0 0 1 1.897.486 5.54 5.54 0 0 1 4.464-2.388c.037-.67.277-1.313.69-1.843a7.47 7.47 0 0 0-7.051 3.745">
</svg>
<div class="">
<h3 class="" aria-hidden="true">Linux</h3>
<small id="linuxDescription">Ubuntu 20.04 and higher</small>
</div>
</label>
</div>
@theme {
/* light theme */
--color-surface: var(--color-);
--color-surface-alt: var(--color-);
--color-on-surface: var(--color-);
--color-on-surface-strong: var(--color-);
--color-primary: var(--color-);
--color-on-primary: var(--color-);
--color-secondary: var(--color-);
--color-on-secondary: var(--color-);
--color-outline: ;
--color-outline-strong: var(--color-);
/* dark theme */
--color-surface-dark: var(--color-);
--color-surface-dark-alt: var(--color-);
--color-on-surface-dark: var(--color-);
--color-on-surface-dark-strong: var(--color-);
--color-primary-dark: var(--color-);
--color-on-primary-dark: var(--color-);
--color-secondary-dark: var(--color-);
--color-on-secondary-dark: var(--color-);
--color-outline-dark: var(--color-);
--color-outline-dark-strong: var(--color-);
/* shared colors */
--color-info: var(--color-);
--color-on-info: var(--color-);
--color-success: var(--color-);
--color-on-success: var(--color-);
--color-warning: var(--color-);
--color-on-warning: var(--color-);
--color-danger: var(--color-);
--color-on-danger: var(--color-);
/* border radius */
--radius-radius: var(--radius);
}
Keyboard Navigation
Key | Action |
---|---|
Tab |
Radio gets the focus
|
Next radio button gets selected | |
Previous radio button gets selected |