Purpose
Let people pick a single option out of a short, related set.
Loading ...
radiogroupGroups two or more radio buttons so only one can be selected at a time. Provides an accessible label and keyboard behavior for the entire set.
Custom-styled radios grouped with semantic fieldset/legend and keyboard support.
Let people pick a single option out of a short, related set.
Contains role="radio" children—never mix with checkboxes.
Announces “radio group” with position (2 of 4, etc.).
Choose plan tiers, shipping methods, yes/no responses.
Switch between modes (light/dark), notifications frequency, etc.
Collect mutually exclusive answers in onboarding or multi-step flows.
aria-labelledby or aria-label must describe the entire group, not individual radios.
Only one radio should be in the tab order at a time. Use roving tabindex to keep focus tight.
Associate helper/error text via aria-describedby for validation guidance.
| Action | Keys | Result |
|---|---|---|
| Move selection | ArrowLeft / ArrowRight / ArrowUp / ArrowDown | Moves focus and selection to adjacent radio. |
| Select option | Space | Activates the focused radio button. |
| Tab | Tab / Shift+Tab | Moves out of the radiogroup once a radio has focus. |
aria-labelledbyRequiredReference a heading or label element to title the group.
aria-describedbyOptionalPoint to helper or error copy that applies to the whole group.
aria-requiredOptionalMark the group required when at least one radio must be selected.
aria-invalidOptionalSet true when validation fails. Pair with descriptive error text.
Ensure only one radio has tabindex="0". Others should use -1 and rely on arrow keys for focus.
Wrap each radio label in a <label> to increase the tap target and automatically link inputs.
Keep DOM order consistent with visual order to avoid confusing keyboard users.
Announce dynamic changes (e.g., price updates) via aria-live when selection triggers new content.
Fieldset + legend automatically label the radios.
<fieldset role="radiogroup" aria-labelledby="plan-label">
<legend id="plan-label">Select a billing plan</legend>
<label>
<input type="radio" name="plan" value="starter" checked />
Starter — $19/mo
</label>
<label>
<input type="radio" name="plan" value="growth" />
Growth — $49/mo
</label>
<label>
<input type="radio" name="plan" value="scale" />
Scale — $99/mo
</label>
</fieldset>Div-based radios require role and aria-checked.
<div role="radiogroup" aria-label="Delivery speed">
<div role="radio" aria-checked="true" tabindex="0">Standard (3–5 days)</div>
<div role="radio" aria-checked="false" tabindex="-1">Express (2-day)</div>
<div role="radio" aria-checked="false" tabindex="-1">Overnight</div>
</div>Use concise labels so screen readers can quickly parse all options.
Add helper text describing what changes when an option is selected.
Use strong focus + selected indicators for sighted users.
Allowing multiple radios to be selected simultaneously
Ensure changing one radio automatically unchecks the rest.
Screen readers announce “radio button” with no context.
Add aria-labelledby or wrap in a fieldset + legend.
Child role that represents each option.
Learn moreGeneric grouping role when fieldset is impractical.
Learn moreContains entire forms that may include radiogroups.
Learn more