Radio
Material Design 3 radio buttons for single selection from multiple options. Includes keyboard navigation, accessibility support, and all interaction states. Not intended for binary on/off choices; use a switch, or for multi-select, use checkboxes.
Basic Usage
Use radios for single selection within a group. This is the
recommended baseline because it enforces mutual exclusivity within a
name group and uses native arrow key navigation.
<ds-radio name="basic" value="option" label="Single option"></ds-radio>
Initial Value
Preselect a sensible default option for the group.
<ds-radio name="delivery" value="standard" label="Standard" checked></ds-radio> <ds-radio name="delivery" value="express" label="Express"></ds-radio>
Variants
Use vertical or horizontal layouts based on space and scanability.
Vertical Group
- Use when: Options have longer labels requiring full-width layout.
- Avoid when: Fewer than 3 short options can scan faster in a row.
<ds-radio name="size" value="small" label="Small" checked></ds-radio> <ds-radio name="size" value="medium" label="Medium"></ds-radio> <ds-radio name="size" value="large" label="Large"></ds-radio>
Horizontal Group
- Use when: 2–3 short labels benefit from side-by-side comparison.
- Avoid when: Labels are long or the layout is narrow.
<ds-radio name="color" value="red" label="Red" checked></ds-radio> <ds-radio name="color" value="green" label="Green"></ds-radio> <ds-radio name="color" value="blue" label="Blue"></ds-radio>
Sizes
Use size to align with layout density.
<ds-radio name="size-demo" value="sm" size="sm" label="Small"></ds-radio> <ds-radio name="size-demo" value="md" size="md" label="Medium" checked></ds-radio> <ds-radio name="size-demo" value="lg" size="lg" label="Large"></ds-radio>
States
Show unselected, selected, disabled, and error states.
Default and Selected
<ds-radio name="group1" value="option1" label="Unselected"></ds-radio> <ds-radio name="group1" value="option2" label="Selected" checked></ds-radio>
Disabled
<ds-radio label="Disabled Unselected" disabled></ds-radio> <ds-radio label="Disabled Selected" checked disabled></ds-radio>
Error
<ds-radio label="Error State" error></ds-radio> <ds-radio label="Error Selected" checked error></ds-radio>
Interactive Example
Select your preferred contact method:
API
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
required |
boolean | false | Whether one radio in the group must be checked. Set it on any radio in the group. Blocks the enclosing form's submission until satisfied. |
checked |
Boolean | false | Whether the radio is selected |
disabled |
Boolean | false | Whether the radio is disabled |
error |
Boolean | false | Whether the radio has an error state |
name |
String | "" | Group identifier - radios with same name form a group |
value |
String | "" | Value to identify this specific radio option |
label |
String | "" |
Label text rendered next to the control and mirrored into
aria-label for its accessible name
|
size |
String | "" |
Size of the radio (sm, md,
lg)
|
Forms
The checked radio submits its value (default "on"). Radios group as native ones do: same name, same form, same DOM tree — so two forms can each have their own plan group. required is a group property: every radio in the group is invalid until one is checked. It resets with its form, and a disabled <fieldset> disables it. form, validity, validationMessage, checkValidity() and reportValidity() behave as on a native control.
Properties
| Property | Type | Description |
|---|---|---|
checked |
Boolean | Get or set the checked state |
disabled |
Boolean | Get or set the disabled state |
error |
Boolean | Get or set the error state |
name |
String | Get or set the group name |
value |
String | Get or set the value |
label |
String | Get or set the label text |
size |
String | Get or set the size |
Events
| Event | Detail | Description |
|---|---|---|
ds-radio:change |
{ checked, value, name } |
Fired when the radio is selected |
CSS Parts
| Part | Description |
|---|---|
| None. | |
CSS Custom Properties
| Property | Description |
|---|---|
--md-sys-color-primary |
Color of selected radio |
--md-sys-color-on-surface-variant |
Color of unselected radio |
--md-sys-color-error |
Color for error state |
--md-sys-state-hover-opacity |
Opacity for hover state layer |
--md-sys-state-focus-opacity |
Opacity for focus state layer |
--md-sys-state-pressed-opacity |
Opacity for pressed state layer |
--ds-radio-size |
Radio size (default: var(--ds-size-icon-md, 20px)) |
--ds-radio-dot-size |
Inner dot size (default: calc(var(--ds-radio-size) / 2)) |
--ds-radio-state-layer-size |
State layer size (default: var(--ds-size-hit-area, 40px)) |
Accessibility
Keyboard Map
| Key | Context | Expected Result |
|---|---|---|
Tab |
Outside radio group | Focuses the selected radio in the group, or first if none selected. |
Arrow Up / Arrow Left |
Radio focused | Moves selection to previous radio in group. |
Arrow Down / Arrow Right |
Radio focused | Moves selection to next radio in group. |
Space |
Radio focused | Selects the focused radio. |
Semantics
- Radio buttons expose
role="radio". aria-checkedreflects the checked state.aria-disabledreflects the disabled state.-
The
labelattribute is mirrored intoaria-labelso the radio's accessible name doesn't depend on an external, unassociated label element.
Usage Guidelines
- When to use: User must select exactly one option from a visible set of 2–7 options.
- When not to use: User can select multiple options (use checkboxes); many options are available (use a select); binary on/off (use a switch).
-
Composition: Group radios with the same
nameattribute to enforce mutual exclusivity. Pre-select a sensible default. -
Common mistakes: Using radio buttons where no
selection is valid, omitting the
nameattribute, and not providing labels.