RadioGroup

RadioGroup is used to render a short list of mutually exclusive options.

Page navigation navigation

A RadioGroup's selection should only be saved when the user explicitly submits it (e.g., via a "save" button). RadioGroups are a single tab stop with arrow-key navigation, meaning screen readers can only read an option by selecting it. See saving pattern guidelines for details.

Alternatively, use a SegmentedControl for immediate selection when it's outside a larger form.

Accessibility and usability expectations

Radio buttons must always be part of a group, with a visible group label that provides context.

If a selection from a radio group is required, an indication must be included as part of the group label. Best practice is to use text as the indicator, such as "(required)". Whilst an asterisk is sufficient to meet accessibility requirements, it's meaning may not be understood by all users, and may be difficult to see by users with low vision.

Each radio button must have a clear, descriptive, and permanently visible label so that users understand the purpose of each option.

The option label should appear to the right of the radio button.

The text, including the group label, caption, option labels and error and success message, must meet the minimum contrast requirements of 4.5:1.

The border of a radio button must have a minimum contrast ratio of 3:1 against the background.

A radio button must have a visible focus style. Instead of using the browser's default focus style, which can be difficult to see against certain backgrounds, a custom focus style should be implemented. A custom focus style must have a minimum contrast ratio of 3:1 against the background.

Radio buttons must have a distinct selected state that does not rely solely on colour.

The target size and spacing of radio buttons must be at least 24 by 24 CSS pixels.

The text must be resizable and the text spacing adjustable, and must remain readable, without requiring horizontal scrolling, when zoomed or viewed at a width equivalent to 320 CSS pixels.

Unless a radio button is disabled, it must by focusable. A group of radio buttons should have a single tab stop. Use the arrow keys to navigate and select a radio button.

A radio button must not trap focus or initiate a change of context when focused or selected.

A group of radio buttons must either be contained within a <fieldset> and have a <legend> as the first child to provide the group label, or be contained within a role="region" and have an aria-labelledby to provide the group label.

Each radio button must have an associated <label> to give it an accessible name that is announced by screen readers.

Additional instructions or requirements must be easily discoverable by screen reader users - in general, by having them programmatically associated with the <input> or <fieldset> using aria-describedby. A caption that applies to a radio button is associated with the <input>. A caption that applies to the radio group is associated with the <fieldset>. An error message is associated with the <fieldset>.

The accessible name of each radio button must include any visible text label so that speech recognition users can activate a radio button by saying the visible text label.

A radio button must have the role of radio so that screen readers convey the correct type of control.

The selected state of a radio button must be conveyed to screen readers so blind users knows if it is selected or not.

If a radio button is disabled, the disabled state must be conveyed to screen readers.

Built-in accessibility features

The text, radio button border and custom focus style meet minimum contrast requirements.

The radio buttons have a distinct selected state that does not rely solely on colour.

The radio buttons have sufficient spacing to meet the minimum target and spacing size of 24 by 24 CSS pixels.

The text is resizable and the text spacing adjustable. The component reflows when zoomed or viewed at a width equivalent to 320 CSS pixels.

By default, the component renders a <fieldset> and <legend> to provide the grouping and group label, but can also use aria-labelledby and role="group".

The component renders correctly associated pairs of <label> and <input type="radio">. Using the the native <input type="radio"> ensures that the radio buttons conveys the correct role and selected state to screen readers and has the correct keyboard behaviour.

The group caption, error message and success message is automatically associated with the <fieldset> using aria-describedby. Option captions are automatically associated with the with the relevant <input>.

When a radio button is disabled, the disabled attribute is applied and the disabled state conveyed to screen readers.

Implementation requirements

Ensure the radio group has a visible group label that provides context. The simplest way to do this is to use a RadioGroup.Label. Alternatively, an aria-labelledby that references an external label can be applied to RadioGroup.

RadioGroup.Label has a visuallyHidden prop, but this should not be used.

When using an icon for a leading visual, note that the icon doesn't have a text alternative. They are purely visual, and not conveyed to screen readers. Don't rely on these icons alone to convey meaning – make sure that the text label of the radio button provides sufficient meaning on its own.

How to test the component

Integration tests

  • The radio group has a visible group label that provides a descriptive accessible name
  • Each radio button has a clear and visible label that describes it's purpose
  • If a radio button includes a leading visual icon, the input's purpose is clear from the text label alone

Component tests

  • When a RadioGroup is given a RadioGroup.label, a <fieldset> containing a <legend> as the first child is rendered
  • When a RadioGroup has an aria-labelledby applied, instead of a RadioGroup.label, a <div> with a role="group" and an aria-labelledby is rendered instead of a <fieldset> and <legend>
  • The component renders correctly associated pair of <label> and <input type="radio">
  • All text, including labels, captions, error and success messages, meets the minimum contrast requirements of 4.5:1
  • The radio button border, selected style and custom focus style meet the minimum contrast requirement of 3:1
  • The radio buttons have sufficient spacing to meet the minimum target and spacing size of 24 by 24 CSS pixels
  • The content remains readable, without requiring horizontal scrolling, when zoomed or viewed at a width equivalent to 320 CSS pixels
  • If there is a group caption, it is associated with the <fieldset> using aria-describedby
  • If there is option caption, it is associated with the appropriate <input> using aria-describedby
  • If a radio button is disabled, the disabled attribute is present