Radio group
Picks one of a few choices.
Checked
falsedefault
true
States
rest
hover
held
focus-visible
chosen
invalid
disabled
Usage
When to use it
- Use
- Exactly one of two to six choices, each needing a line about its consequence.
- Use
- A form setting saved with the form, where the person should compare before choosing.
- Not for
- Two to five views of the same thing, switched at once. Use Segmented control.
- Not for
- Any number can be on. Use Checkbox.
- Not for
- A single on or off that applies at once. Use Switch.
Rules
6 rules
- Must
- Use RadioGroupOption for each choice so its label and description share one target and are read together. Because a loose RadioGroupItem with text beside it has no name, and only the 16px circle takes the press.
- Must
- Name the group with a FieldLegend in a FieldSet, or aria-label. Because arrowing into an unnamed group, a screen reader announces the options with no question.
- Must
- Give the group a value or defaultValue unless choosing nothing is a real answer. Because a radio cannot be cleared once chosen, so an empty start the person must fix looks like a missing default.
- Never
- Colour the chosen radio or swap its small glaze for a flat fill. Because small glaze (glaze-sm) is how Glaze shows a chosen small control, and colour means status.
- Should
- Say why a disabled option is out of reach in its description.
- Should
- Keep a group to about six options; past that, use a select. Because a long column of circles pushes the rest of the form down and is slow to compare.
State order
7 states, highest first
- 1
- disabled
- 2
- invalid
- 3
- chosen
- 4
- held
- 5
- focus-visible
- 6
- hover
- 7
- rest
Accessibility
4 checks
- role="radiogroup" with one tab stop; each radio is named by its label and described by its consequence.
- The open circle is --line-strong, 3.3:1 on paper; the chosen one is small glaze with a white dot (9.5:1 at the centre), so it reads without colour.
- Each circle is 16px with a 28px hit area, and the whole option row is the target.
- Focus is the 2px ink ring on the circle.
Keyboard
3 keys
- Arrow keys
- Move to the next or previous option and choose it, wrapping at the ends.
- Space
- Chooses the focused option.
- Tab
- Enters on the chosen option and leaves the group.
Edge cases
6 edge cases
- Long description
- Wraps under the label; the circle stays on the first line.
- Nothing chosen
- Tab lands on the first enabled option.
- Disabled option
- Arrow keys skip it; its text turns the disabled colour.
- Right to left
- The circle moves to the start with the label, and the arrows follow the reading order.
- Dark theme
- The chosen circle turns light glaze with a dark dot.
- Forced colors
- The chosen circle takes Highlight with a HighlightText dot.
API
5 props
value, defaultValue, onValueChangeBase UI RadioGrouparia-invalidbooleandefaultfalsedisabled, readOnly, required, nameBase UIRadioGroupOption label, descriptionReactNodeRadioGroupItem valuestring
Tokens
18 tokens
--paper- #ffffff
--field- #efefef
--pressed- rgb(5 5 5 / 0.10)
--line-strong- rgb(5 5 5 / 0.45)
--line-faint- rgb(5 5 5 / 0.06)
--text-1- rgb(5 5 5 / 0.80)
--text-2- rgb(5 5 5 / 0.60)
--fail- #e35e49
--glaze-sm-top- #6b6b6b
--glaze-sm-mid- #3d3d3d
--glaze-sm-bottom- #232323
--glaze-sm-highlight- rgb(255 255 255 / 0.30)
--glaze-sm-rim- rgb(0 0 0 / 0.55)
--glaze-sm-text- rgb(255 255 255 / 0.92)
--radius-pill- 999px
--type-label- 500 13px/1.35 var(--font-sans)
--type-body-sm- 400 13px/1.5 var(--font-sans)
--focus- rgb(5 5 5 / 0.80)