Forms & Input

Radio Group

Available

Selects one option from many. A prime example of arrow key navigation with roving tabindex.

What Is a Radio Group?

A radio button is a UI control that lets you choose exactly one option from a set. It's used for things like payment methods, sizes, and shipping options — any time you need to pick one and only one. A set of these buttons is called a radio group.

The difference from checkboxes: checkboxes allow multiple selections, while radios allow only one. The key challenge is conveying both this "only one" rule and the group's label to users who can't see the screen.

Why Does Accessibility Matter?

The fastest path is to wrap native radio inputs with the same name in a <fieldset> +<legend>.

Live Demo (Recommended Implementation)

A radio group for choosing a payment method. Without using a mouse, try pressing Tab to enter the group, then use the arrow keys.

Accessible Radio Group
Payment Method

Try it: Tab into the group → ↑ ↓ ← → to move between options (moving = selecting). Tab again to leave the group.

Tip

In a radio group, Tab stops only once for the entire group(not on each individual option). Navigation within the group is handled by arrow keys. This is the "roving tabindex" keyboard pattern, and native radios implement it automatically.

Keyboard Interaction

KeyActionPriority
TabEnter / leave the group (focus lands on the selected item)Required
/ Move to the next option and select itRequired
/ Move to the previous option and select itRequired
SpaceSelect the currently focused optionRequired

Note

All of these interactions come automatically when you use<input type="radio"> elements grouped under the same name. You don't need to write any arrow key handling yourself.

Required WAI-ARIA Roles & Attributes

With native elements, almost no ARIA attributes are needed.

TargetAttribute / RoleMeaning
Each option<input type="radio"> + same nameAutomatically provides the radio role, single-selection behavior, and arrow key navigation.
Label<label>The accessible name for each option. Clicking the label also selects the option.
Group<fieldset> + <legend>Groups the options together and provides the group name (e.g., the question text).

Note

If you absolutely must build a custom implementation, wrap items in role="radiogroup", give each item role="radio" + aria-checked, and implement roving tabindex (only the selected item gets tabindex="0", all others get tabindex="-1") along with manual arrow key handling. Using native elements makes all of this unnecessary.

Implementation: Recommended Pattern (Good)

Good / Recommended

Simply wrap native radio inputs with the same name in a <fieldset> + <legend>.

Markup:

<fieldset>
  <legend>Payment Method</legend>

  <!-- Grouped by the same name. Arrow key navigation & selection work natively -->
  <label>
    <input type="radio" name="pay" value="card" checked> Credit Card
  </label>
  <label>
    <input type="radio" name="pay" value="bank"> Bank Transfer
  </label>
  <label>
    <input type="radio" name="pay" value="cod"> Cash on Delivery
  </label>
</fieldset>

Script:

// No JS required.
// Grouping radios under the same name gives you "select only one",
// "arrow key navigation & selection", and "Tab into the group"
// — all as built-in browser behavior.

Anti-pattern (Bad)

Below is a "radio-like" UI built with <div> elements.You can select options by clicking with a mouse, but arrow keys don't work and Tab won't even stop here.Neither the group name nor the "select only one" semantics are conveyed to assistive technologies.

Broken Radio Group Built with Divs
Credit Card
Bank Transfer
Cash on Delivery

Try it: Tab doesn't focus any option, arrow keys don't switch selection. Screen readers won't recognize this as a group of choices.

<!-- ❌ Anti-pattern: "radio-like" UI built with divs -->
<div class="radio-list">
  <!-- No role, no name, arrow keys don't work. No group label either -->
  <div class="radio" onclick="select(this)">Credit Card</div>
  <div class="radio" onclick="select(this)">Bank Transfer</div>
  <div class="radio" onclick="select(this)">Cash on Delivery</div>
</div>

Bad / Avoid

Problems with this implementation:

  • Not keyboard accessiblediv elements can't receive focus and don't respond to arrow keys.
  • No group semantics — neither role="radiogroup" nor <fieldset> is present.
  • "Select only one" is not conveyed — without role="radio" / aria-checked, the state and position are never announced.
  • Using checkboxes as a substitute for radios is also wrong (they allow multiple selections, reversing the intended semantics).

Implementation Checklist


Source (English):Radio Group Pattern — W3C APG(opens in a new tab)