Skip to content

Radio - Elements ​

Radios allow users to select a single option from a list of choices.

AndroidreleasedElementsreleasediOSreleasedReactreleasedVuereleased

Accessibility ​

Usage ​

A radio input typically consists of two components:

  • <w-radio-group> - A grouping wrapper that manages labeling, help text, roving keyboard focus, and validation for child radios.
  • <w-radio> - A single radio with required and invalid states.

In advanced cases you may use <w-radio> without <w-radio-group>. If you're unsure what's correct in your case, always wrap <w-radio> in a <w-radio-group>.

The components automatically handle:

  • Form integration and constraint validation
  • Required state handling with validation messages
  • Accessibility attributes, keyboard interaction, and labeling
html
<w-radio-group label="Select an option" name="usage">
    <w-radio value="one">Option 1</w-radio>
    <w-radio value="two">Option 2</w-radio>
    <w-radio value="three">Option 3</w-radio>
</w-radio-group>

Validation ​

Set the invalid attribute to display a radio group as invalid, for example if nothing was selected and the group was required.

invalid can be paired with help-text to provide feedback to the user about how to correct the error. However, since the invalid + required use case is so common you can omit help-text to use a generic built-in one.

html
<w-radio-group label="Select an option" name="usage" required invalid>
    <w-radio value="one">Option 1</w-radio>
    <w-radio value="two">Option 2</w-radio>
    <w-radio value="three">Option 3</w-radio>
</w-radio-group>

Examples ​

html
<w-radio-group label="Select an option" name="examples">
    <w-radio value="one">Option 1</w-radio>
    <w-radio value="two">Option 2</w-radio>
    <w-radio value="three">Option 3</w-radio>
</w-radio-group>

Optional ​

Add the optional prop to <w-radio-group> to indicate that the user doesn't have to pick an option.

html
<w-radio-group label="Select an option" name="optional" optional>
    <w-radio value="one">Option 1</w-radio>
    <w-radio value="two">Option 2</w-radio>
    <w-radio value="three">Option 3</w-radio>
</w-radio-group>

Help text ​

Use help-text to give additional context when the label and options are not enough.

html
<w-radio-group label="Select an option" name="help" help-text="Pick whichever you like">
    <w-radio value="one">Option 1</w-radio>
    <w-radio value="two">Option 2</w-radio>
    <w-radio value="three">Option 3</w-radio>
</w-radio-group>

Disabled ​

Keep in mind that using disabled is an anti-pattern.

There will always be users who don't understand why an element is disabled, or users who can't even see that it is disabled because of poor lighting conditions or other reasons.

Please consider more informative alternatives before choosing to use disabled on an element.

html
<w-radio-group label="Select an option" name="disabled" disabled>
    <w-radio value="one">Option 1</w-radio>
    <w-radio value="two">Option 2</w-radio>
    <w-radio value="three">Option 3</w-radio>
</w-radio-group>

Radio and Radio Group Styling ​

This document covers the styling API for both <w-radio> (individual radio buttons) and <w-radio-group> (the container that manages them).

Quick Start ​

html
<w-radio-group label="Choose a size" name="size">
  <w-radio value="small">Small</w-radio>
  <w-radio value="medium">Medium</w-radio>
  <w-radio value="large">Large</w-radio>
</w-radio-group>

Customize via component tokens:

css
/* Style all radio groups in a section */
.settings {
  --w-c-radio-group-gap: 12px;
  --w-c-radio-size: 2.4rem;
}

Styling Philosophy ​

Before customizing, remember that changing defaults can create inconsistent experiences. Prefer the defaults.

  • Component tokens for size, spacing, color, and state styling
  • Parts only for small, one-off tweaks
  • Avoid relying on internal class names

Radio Group (<w-radio-group>) ​

Parts ​

PartTargetsUse Case
form-controlThe <fieldset> wrapperOuter container tweaks
form-control-labelThe group label elementLabel typography overrides
form-control-inputContainer for radio buttonsAdjust layout/flow of radios
help-textHelp text / error messageStyle hint text

Example:

css
w-radio-group::part(form-control-label) {
  text-transform: uppercase;
}

w-radio-group::part(form-control-input) {
  flex-direction: row; /* horizontal radios */
}

Component Tokens ​

Label ​

TokenPurposeDefault
--w-c-radio-group-label-font-sizeLabel font sizevar(--w-font-size-s)
--w-c-radio-group-label-line-heightLabel line heightvar(--w-line-height-s)
--w-c-radio-group-label-font-weightLabel font weight700
--w-c-radio-group-label-colorLabel text colorvar(--w-s-color-text)
--w-c-radio-group-label-color-disabledLabel color when disabledvar(--w-s-color-text-disabled)
--w-c-radio-group-label-padding-bottomSpace below label16px

Optional Indicator ​

TokenPurposeDefault
--w-c-radio-group-optional-font-weight"Optional" text weight400
--w-c-radio-group-optional-color"Optional" text colorvar(--w-s-color-text-subtle)
--w-c-radio-group-optional-margin-inline-startSpace before "Optional"0.5rem

Radio Spacing ​

TokenPurposeDefault
--w-c-radio-group-gapGap between radio buttons16px

Help Text ​

TokenPurposeDefault
--w-c-radio-group-help-text-margin-block-startSpace above help text16px
--w-c-radio-group-help-text-font-sizeHelp text font sizevar(--w-font-size-xs)
--w-c-radio-group-help-text-line-heightHelp text line heightvar(--w-line-height-xs)
--w-c-radio-group-help-text-colorHelp text colorvar(--w-s-color-text-subtle)
--w-c-radio-group-help-text-color-disabledHelp text color when disabledvar(--w-s-color-text-disabled)
--w-c-radio-group-help-text-color-errorHelp text color when invalidvar(--w-s-color-text-negative)

Example:

css
w-radio-group {
  --w-c-radio-group-gap: 12px;
  --w-c-radio-group-label-font-weight: 600;
  --w-c-radio-group-help-text-color: var(--w-s-color-text);
}

Individual Radio (<w-radio>) ​

Parts ​

PartTargetsUse Case
baseWrapper containing control and labelContainer-level adjustments
controlRadio control (circle)Alignment or sizing tweaks
labelLabel contentTypography overrides

Example:

css
w-radio::part(label) {
  font-weight: 600;
}

w-radio::part(control) {
  margin-top: 1px;
}

Component Tokens ​

Layout & Size ​

TokenPurposeDefault
--w-c-radio-gapSpace between control and label8px
--w-c-radio-sizeWidth/height of control2rem
--w-c-radio-radiusBorder radius50%
--w-c-radio-border-widthBorder width1px
--w-c-radio-checked-border-widthBorder width when checked0.6rem

Colors ​

TokenPurposeDefault
--w-c-radio-bgControl backgroundvar(--w-s-color-background)
--w-c-radio-border-colorControl border colorvar(--w-s-color-border-strong)
--w-c-radio-border-color-checkedBorder when checkedvar(--w-s-color-border-selected)
--w-c-radio-border-color-invalidBorder when invalidvar(--w-s-color-border-negative)
--w-c-radio-label-colorLabel text colorcurrentColor

Disabled State ​

TokenPurposeDefault
--w-c-radio-bg-disabledBackground when disabledvar(--w-s-color-background-disabled-subtle)
--w-c-radio-border-color-disabledBorder when disabledvar(--w-s-color-border-disabled)
--w-c-radio-label-color-disabledLabel color when disabledvar(--w-s-color-text-disabled)
--w-c-radio-cursor-disabledCursor when disablednot-allowed

Typography ​

TokenPurposeDefault
--w-c-radio-label-font-sizeLabel font sizevar(--w-font-size-m)
--w-c-radio-label-line-heightLabel line heightvar(--w-line-height-m)

Focus ​

TokenPurposeDefault
--w-c-radio-outline-widthFocus outline width2px
--w-c-radio-outline-colorFocus outline colorvar(--w-s-color-border-focus)
--w-c-radio-outline-offsetFocus outline offsetvar(--w-outline-offset, 1px)

Interaction ​

TokenPurposeDefault
--w-c-radio-cursorCursor in enabled statepointer

Motion ​

TokenPurposeDefault
--w-c-radio-transitionTransition for controlborder-color 150ms, border-width 150ms, background-color 150ms

Note: Transitions automatically disable when prefers-reduced-motion: reduce is active.


Complete Examples ​

Horizontal Radio Group ​

css
w-radio-group::part(form-control-input) {
  flex-direction: row;
  flex-wrap: wrap;
}

Larger Radio Buttons ​

css
w-radio {
  --w-c-radio-size: 2.4rem;
  --w-c-radio-checked-border-width: 0.8rem;
}

Custom Colors ​

css
w-radio {
  --w-c-radio-border-color-checked: var(--w-s-color-border-success);
}

Tighter Spacing ​

css
w-radio-group {
  --w-c-radio-group-gap: 8px;
  --w-c-radio-group-label-padding-bottom: 8px;
}

Architecture Note ​

Radio-group uses <fieldset> which is the semantic HTML element for grouping form controls. Note that <w-checkbox-group> currently uses <div> instead - this inconsistency may be addressed in a future major version to align both components on the more accessible <fieldset> approach.

<w-radio-group> API ​

Unless otherwise noted all properties are HTML attributes (as opposed to JavaScript object properties).

Properties ​

NameTypeDefaultSummary
disabledbooleanfalseDisables the radio group and all child radios.
help-textstring""Help text for the radio group.
invalidbooleanfalseMarks the radio group as invalid.
labelstring""Label for the radio group.
namestring | nullnullThe name of the select when submitting the form.
optionalbooleanfalseWhether to show optional text next to the label.
requiredbooleanfalseMakes selecting a radio in the the group required.

Property Details ​

disabled ​

Disables the radio group and all child radios.

  • Type: boolean
  • Default: false

help-text ​

Help text for the radio group.

If you set required and invalid the group gets a default error message, but you can override it with this attribute.

  • Type: string
  • Default: ""

invalid ​

Marks the radio group as invalid.

  • Type: boolean
  • Default: false

label ​

Label for the radio group.

  • Type: string
  • Default: ""

name ​

The name of the select when submitting the form.

  • Type: string | null
  • Default: null

optional ​

Whether to show optional text next to the label.

  • Type: boolean
  • Default: false

required ​

Makes selecting a radio in the the group required.

  • Type: boolean
  • Default: false

<w-radio> API ​

Properties ​

NameTypeDefaultSummary
checkedbooleanfalseDraws the radio in a checked state (reflected to attribute).
disabledbooleanfalseDisables the radio.
invalidbooleanfalseDraws the radio in an invalid state.
namestring-The name of the radio, submitted as a name/value pair with form data.
requiredbooleanfalseMakes the radio a required field.
valuestring | nullnullThe radio's value. When selected, the radio group will receive this value.

Property Details ​

checked ​

Draws the radio in a checked state (reflected to attribute).

  • Type: boolean
  • Default: false
disabled ​

Disables the radio.

  • Type: boolean
  • Default: false
invalid ​

Draws the radio in an invalid state.

  • Type: boolean
  • Default: false
name ​

The name of the radio, submitted as a name/value pair with form data.

  • Type: string
  • Default: -
required ​

Makes the radio a required field.

  • Type: boolean
  • Default: false
value ​

The radio's value. When selected, the radio group will receive this value.

  • Type: string | null
  • Default: null

Questions? ​

Feel free to ask any questions on usage in the Warp DS Slack channel: #warp-design-system