Skip to content
Fleetline

Radio

Usage

Use radios when people must choose exactly one option from a short list (up to about 6) and it helps to see all options at once — service type, priority, which bay. Use a select for longer lists, checkboxes when several answers are allowed.

Anatomy

  1. Circle — input[type=radio].radio__input (native, appearance: none), 24px
  2. Dot — ::before, scales in when checked
  3. Label — label.radio__label[for]; optional .radio__title for cards
  4. Hint (optional) — .radio__hint
  5. Group — fieldset.radio-group with legend, hint, error and .radio-group__items

Examples

Hover and focus-visible are frozen with .is-hover and .is-focus-visible, which share their rules with the real pseudo-classes.

Radio

Out of service until 14 March.

How urgent is the repair?

Error: Select how urgent the repair is.

<div class="radio">
        <input class="radio__input" type="radio" id="svc-scheduled" name="service" value="scheduled">
        <label class="radio__label" for="svc-scheduled">Scheduled service</label>
      </div>
      <!-- Required radios get :user-invalid after interaction; a .field__error in the group marks the whole group -->

Radio group

Which bay should KX-219 go to?

Max 3.5 t.

Odometer unit
Service plan

Every 10,000 km or 6 months. Oil, filters, safety check.

Every 20,000 km or 12 months. Adds brakes, coolant, belts.

Not available for vehicles under 3 years old.

<fieldset class="fieldset radio-group [radio-group--horizontal | radio-group--cards]">
        <legend class="fieldset__legend">Service plan</legend>
        <div class="radio-group__items">
          <div class="radio">
            <input class="radio__input" type="radio" id="plan-interim" name="plan" aria-describedby="plan-interim-hint">
            <label class="radio__label" for="plan-interim"><span class="radio__title">Interim</span></label>
            <p class="radio__hint" id="plan-interim-hint">Every 10,000 km or 6 months.</p>
          </div>
          …
        </div>
      </fieldset>

API

HookValuesPurpose
.radio, .radio__input, .radio__label, .radio__title, .radio__hintblock / partsOne option
.radio-group (+ .fieldset), .radio-group__itemsblock / partGroup
.radio-group--horizontalmodifier classRow of 2–3 short options
.radio-group--cardsmodifier classBordered tiles; label stretches over the tile
name, checked, disabled, requiredattributeNative states and grouping
.field__error inside the group, :user-invalidpart / pseudo-classInvalid
.is-hover | .is-focus-visibledocs-only classFreezes a state

Do and don't

Priority
Do ask the question in the legend and list every option.
Don't use a single radio for an opt-in — it can't be unchecked. Use a checkbox.

Accessibility

Keyboard interaction
KeyBehavior
TabInto the group (focuses the checked radio, or the first) and out of it — one tab stop
↓ → / ↑ ←Next / previous option, selecting it (native, wraps)
SpaceSelects the focused radio if none is checked

Tokens

Custom propertyPurpose
--input-border, --input-bgUnchecked circle
--color-action-primary-bg | -hoverChecked ring and dot
--color-selected-bg, --color-selected-borderSelected card
--color-border-default, --color-bg-surface, --radius-mdCard
--color-border-invalidInvalid
--color-bg-muted, --color-text-disabledDisabled