Radio
Radio buttons let people select one option from a set of options.
<div role="radiogroup" aria-label="Delivery address">
<div>
<md-gb-radio id="home" name="address" value="home" checked></md-gb-radio>
<label for="home">Home</label>
</div>
<div>
<md-gb-radio id="office" name="address" value="office"></md-gb-radio>
<label for="office">Office</label>
</div>
</div>Install with shadcn/ui: npx shadcn@latest add https://material-web.dev/3.0/r/md-radio.json (setup)
Usage guidelines
Link to “Usage guidelines”- Use radios for a single choice. Pick radio buttons, not switches, when only one option can be selected from a list; use checkboxes when several can.
- Show every option. Radios expose all the choices, so use them for five or fewer; consider a menu when space is tight.
- Always add a label. Each radio needs its own scannable label, and a person can select either the radio or its label.
- Preselect one and stack them. List radios vertically with one option already selected, and avoid nesting them.
Anatomy
Link to “Anatomy”A radio is one element, paired with an adjacent label.
<md-gb-radio id="anatomy-radio" name="anatomy" value="email" checked></md-gb-radio>
<label for="anatomy-radio">Email</label>Examples
Link to “Examples”Group
Link to “Group”Radios with the same name form a group, and only one can be selected. Add checked to the one selected at the start, and value to identify the selection in a form.
<form>
<div role="radiogroup" aria-label="Pet">
<div>
<md-gb-radio id="cats" name="pet" value="cats"></md-gb-radio>
<label for="cats">Cats</label>
</div>
<div>
<md-gb-radio id="dogs" name="pet" value="dogs" checked></md-gb-radio>
<label for="dogs">Dogs</label>
</div>
<div>
<md-gb-radio id="birds" name="pet" value="birds"></md-gb-radio>
<label for="birds">Birds</label>
</div>
</div>
</form>Required
Link to “Required”Add required to any radio in the group to require a selection before the form submits.
<form>
<div role="radiogroup" aria-label="Plan">
<div>
<md-gb-radio id="monthly" name="plan" value="monthly" required></md-gb-radio>
<label for="monthly">Monthly</label>
</div>
<div>
<md-gb-radio id="yearly" name="plan" value="yearly"></md-gb-radio>
<label for="yearly">Yearly</label>
</div>
</div>
</form>Disabled
Link to “Disabled”Add disabled to a radio that can't be selected right now.
<div role="radiogroup" aria-label="Shipping">
<div>
<md-gb-radio id="standard" name="shipping" checked></md-gb-radio>
<label for="standard">Standard</label>
</div>
<div>
<md-gb-radio id="express" name="shipping" disabled></md-gb-radio>
<label for="express">Express</label>
</div>
</div>Density
Link to “Density”Set density from 0 (default) down to -3 to shrink the radio by 4px per step. The touch target stays 48px. Keep it off by default and let people opt in.
<div role="radiogroup" aria-label="Size">
<div>
<md-gb-radio id="small" name="size" density="-2" checked></md-gb-radio>
<label for="small">Small</label>
</div>
<div>
<md-gb-radio id="large" name="size" density="-2"></md-gb-radio>
<label for="large">Large</label>
</div>
</div>Accessibility
Link to “Accessibility”- Place radios in a
role="radiogroup"and label the group witharia-labeloraria-labelledby. - Name each radio with a
<label for>that points at itsid. Use anaria-labelonly for a radio with no visible label. - Don't wrap a radio in its
<label>; screen readers then can't announce the number of radios in the group. - Tab moves focus to the selected radio of a group, and the arrow keys move the selection between radios. Space selects the focused radio.
- Once a radio is selected the group can't be cleared, so add a "None" option or a "Clear selection" control if people may opt out.
Compatibility
Link to “Compatibility”Material Design 3Spec checked75% tokens
44 of 84 buildable spec units are tested, 8 are excluded with a written reason and 0 are uncovered (the target is 0). 18 of 24 token declarations match the spec (75%), and 6 have no spec token.
radio-button on m3.material.io (opens in a new tab) How compliance is measured
BaselineWidely availableChrome 124Edge 124Firefox 125Safari 17.4
The component’s own CSS and JavaScript rely only on web platform features that are Baseline widely available: it works in Chrome 124, Edge 124, Firefox 125, Safari 17.4 and later.
It uses no newer features.
Browser support Learn more about Baseline (opens in a new tab)
WAI-ARIAaxe and ARIA 1.3 passRadio Group
Roles the component renders: radio (opens in a new tab).
Follows the WAI-ARIA Authoring Practices: Radio Group (opens in a new tab).
2 rendered states run through axe-core and the WAI-ARIA 1.3 role and attribute rules in a real browser, with no known gaps.
WAI-ARIA 1.3 (opens in a new tab) ARIA Authoring Practices (opens in a new tab) Accessibility
Lighthouse99 · 100 · 100 · 100
Performance Accessibility Best practices SEO
Audits under 90:
- Eliminate render-blocking resources
- Minify JavaScript
- Enable text compression
- Network dependency tree
- Render blocking requests
Lighthouse 12.8.2 (desktop, 2026-11-08) on the component alone: its first example on a page of its own, without this site's shell. The modules are the development build (not bundled or minified), so the performance score is indicative.
API reference
Link to “API reference”<md-gb-radio>
Link to “<md-gb-radio>”A Material Design component.
Properties
Link to “Properties”| Property | Attribute | Type | Default |
|---|---|---|---|
checkedWhether or not the radio is selected. |
checked |
boolean |
|
densityThe density, from 0 (default) to -3. Each step down removes 4px from the radio's layout box (48px) and state layer (40px); the touch target stays 48px. Values are clamped to that range. radio-button.md: don't apply density by default; let people opt in to a denser layout. |
density |
Density |
|
requiredWhether or not the radio is required. If any radio is required in a group, all radios are implicitly required. |
required |
boolean |
false |
valueThe element value to use in form submission when checked. |
value |
string |
'on' |
Events
Link to “Events”| Event | Description |
|---|---|
changeEvent |
Fired when the radio is checked (but not unchecked). |
inputInputEvent |
Fired when the radio is checked (but not unchecked). |
CSS parts
Link to “CSS parts”| Part | Description |
|---|---|
::part(radio) |
The radio's root element. |
CSS custom properties
Link to “CSS custom properties”| Property | Description |
|---|---|
--density-step |
Size removed per density step. |
--icon-color |
|
--icon-size |
|
--state-layer-color |
|
--state-layer-shape |
|
--state-layer-size |
State layer size at density 0. |
--target-size |
The minimum touch target size, kept at any density. |