Radio
A radio allows users to select exactly one option from a set.
Ready to use
Radio buttons allow users to select exactly one option from a list of at least two mutually exclusive choices. Selecting one option automatically deselects the previously selected one. The component is fully responsive and intentionally designed to be used across all viewports.
Anatomy
Section titled “Anatomy”- Radio button
- Label
When to use it
Section titled “When to use it”Use radio buttons when:
- The user must select exactly one option from a small list of mutually exclusive choices (typically 2–5).
- All available options should be visible at a glance for quick comparison.
- You want to provide a clear “recommended” or “current” state by pre-selecting a default.
Avoid radio buttons when:
- The user needs to select multiple items — use checkboxes.
- The list contains more than 5–6 options — use a dropdown to save space.
- The action is a binary on/off that takes effect immediately without a submit button — use a toggle switch.
Properties
Section titled “Properties”State
Default, Hover, Selected, Disabled, Disabled-Selected, and Focus. Selected fills the control; disabled mutes it but stays visible; focus shows a 2 px outline around the entire item.
Size
Two sizes — Small (typography-body-7) for dense forms, Large (typography-body-6) for primary selections or hero comparisons. Both keep the same control size; only the label typography changes.
Label
The visible label sits next to the control and is fully clickable, which keeps the touch target generous. Always associate the label with the input so screen-reader users hear the choice as they navigate.
Platform considerations
Section titled “Platform considerations”Desktop
Vertical stacking keeps the comparison readable. Keyboard arrow keys move focus logically between options inside the group.
Tablet
Same vertical stack. Touch and pointer both work because the entire label area is clickable.
Mobile
Stick with the vertical stack and pick the large size for primary choices so the touch target stays comfortable.
Best practices
Section titled “Best practices”Lean on native semantics so keyboard, focus, and assistive-tech behaviour come for free.
Do
Use radio buttons when the user must select exactly one option, wrap groups in a <fieldset> with a <legend>, pre-select a sensible default when one exists, associate a visible label with every radio, provide clear visual feedback for selected, unselected, and disabled states, and ensure arrow-key navigation moves focus logically between options.
Don't
Don’t reach for radio buttons when the user can select multiple options (use checkboxes), don’t reach for them when the list contains more than 5–6 options (use a dropdown), don’t reach for them for instant on/off actions (use a toggle), don’t recreate the control with <div> or <span> without ARIA roles, don’t rely on colour alone for the selected state, and don’t remove the browser focus outline unless you replace it with an accessible equivalent.
Content guidelines
Section titled “Content guidelines”Write each label so it stands on its own — users shouldn’t have to read the legend to understand a choice. Keep the wording parallel across the group (“Petrol”, “Hybrid”, “Electric” rather than “Petrol car”, “Hybrid”, “Fully electric vehicles”), use sentence case, and skip trailing punctuation. The group’s legend should pose a clear question or name the dimension the choices vary along.
Styles
Section titled “Styles”A radio allows users to select exactly one option from a set.
<label class="tng-radio-control"> <input type="radio" name="delivery" checked /> <span>Home delivery</span></label><label class="tng-radio-control"> <input type="radio" name="delivery" /> <span>Click and collect</span></label>Elements
Section titled “Elements”Grouping
Section titled “Grouping”Group related radios in a <fieldset> with a <legend> so assistive technology announces the group context.
<fieldset class="tng-stack"> <legend class="tng-text-title is-8 mb-xl"> Contact preference </legend> <label class="tng-radio-control"> <input type="radio" name="contact" checked /> <span>Email</span> </label> <label class="tng-radio-control"> <input type="radio" name="contact" /> <span>SMS</span> </label></fieldset><label class="tng-radio-control is-sm"> <input name="size" type="radio" /> <span>Small</span></label><label class="tng-radio-control is-lg"> <input name="size" type="radio" /> <span>Large</span></label>States
Section titled “States”Disabled
Section titled “Disabled”<label class="tng-radio-control"> <input type="radio" name="state" disabled /> <span>Disabled</span></label><label class="tng-radio-control"> <input type="radio" name="state" checked disabled /> <span>Selected and disabled</span></label>The radio group follows the WAI-ARIA Radio Group pattern — a set of mutually exclusive options where choosing one clears the rest — and meets WCAG 2.1 AA. An accessible radio group is reachable and operable from the keyboard as a single unit, keeps assistive technology informed of which option is chosen, and gives the group and every option an accessible name — so the choice is clear whether the user is looking at it, listening to it, or tabbing through it.
For designers
Section titled “For designers”- Every option and state must maintain accessible contrast on every supported surface. Source: WCAG 1.4.3 Contrast (Minimum).
- The selected state must never be conveyed by colour alone — the filled control and its border carry the state alongside any colour change. Source: WCAG 1.4.1 Use of Color.
- Focus styles must stay visible, meet contrast requirements on every supported surface, and be clearly distinguishable from hover. Source: WCAG 2.4.7 Focus Visible.
- Use semantic colour tokens (e.g.
foreground/neutral/default) rather than fixed values, so the component adapts correctly across themes and surfaces.
For developers
Section titled “For developers”Build the group from native <input type="radio"> elements that share one name. The browser then treats them as a single composite: it enforces single selection, moves focus between options with the arrow keys, and reports which option is chosen — all without custom ARIA. Because the semantics are native, add no role or aria-* to reproduce them; reserve markup for wiring up accessible names, which the Labelling elements section covers per element.
Keyboard interaction
Section titled “Keyboard interaction”| Key | Action |
|---|---|
| Tab / Shift + Tab | Move focus into the group (landing on the selected option), or out to the next / previous control |
| ↓ / → | Move to and select the next option |
| ↑ / ← | Move to and select the previous option |
| Space | Select the focused option |
The full row — control plus its label — is the interactive target, keeping it comfortably above the WCAG AA minimum for touch. Source: WCAG 2.5.8 Target Size (Minimum).
Focus order
Section titled “Focus order”The whole group is a single tab stop: Tab enters it once, landing on the selected option (or the first when none is selected), and the arrow keys then rove the selection within it — a roving tabindex keeps only that entry option in the tab sequence while the rest carry tabindex="-1". The keys that drive this are in the Keyboard interaction table above.
- Focused option
Source: WCAG 2.4.3 Focus Order.
Labelling elements
Section titled “Labelling elements”Give the group and every option the role, name, and state assistive technology needs.
Radio group
The <fieldset> exposes the options as one group; its <legend> gives the group its accessible name, which assistive technology announces before each option so the category is heard once. Keep the legend a clear question or the dimension the options vary along.
Radio option
Each native <input type="radio"> reports its radio role automatically and takes its accessible name from the <label> that wraps it — the <span> text — so keep that text self-describing. The native checked attribute conveys the selected state; no aria-checked is needed.
Source: WCAG 4.1.2 Name, Role, Value.