Skip to content

COMPONENT

Choice

Checkbox, radio and switch. Real inputs with their paint replaced — never a span pretending to be a control.

All three, in every state

Tab through them. They check with the keyboard, they submit with a form, and they announce themselves, because they are the real elements.

CHECKBOX
RADIO
SWITCH
HTML
<div class="choice-group">
  <span class="field-label">CHECKBOX</span>
  <label class="choice"><input class="checkbox" type="checkbox"><span class="choice-label">Fixed scope</span></label>
  <label class="choice"><input class="checkbox" type="checkbox" checked><span class="choice-label">Weekly builds</span></label>
  <label class="choice"><input class="checkbox" type="checkbox" data-indeterminate><span class="choice-label">Indeterminate</span></label>
  <label class="choice"><input class="checkbox" type="checkbox" disabled><span class="choice-label">Unavailable</span></label>
</div>
<div class="choice-group">
  <span class="field-label">RADIO</span>
  <label class="choice"><input class="radio" type="radio" name="engagement" checked><span class="choice-label">Project</span></label>
  <label class="choice"><input class="radio" type="radio" name="engagement"><span class="choice-label">Retainer</span></label>
  <label class="choice"><input class="radio" type="radio" name="engagement"><span class="choice-label">Advisory</span></label>
</div>
<div class="choice-group">
  <span class="field-label">SWITCH</span>
  <label class="choice"><input class="switch" type="checkbox" checked><span class="choice-label">On</span></label>
  <label class="choice"><input class="switch" type="checkbox"><span class="choice-label">Off</span></label>
  <label class="choice"><input class="switch" type="checkbox" disabled><span class="choice-label">Disabled</span></label>
</div>

Reference

Read from components/choice.css when this page was built, so it cannot fall behind the stylesheet.

CLASSES.choice.choice-label.checkbox.radio.switch.choice-group
READS--ds-accent--ds-accent-deep--ds-control-h--ds-cream--ds-focus-ring--ds-focus-width--ds-font-body--ds-gap-loose--ds-ground--ds-hairline--ds-hit-min--ds-ink-disabled--ds-ink-faint--ds-ink-on-cream--ds-ink-read--ds-motion-fast--ds-motion-travel--ds-radio-dot--ds-radius-field--ds-radius-pill--ds-radius-round--ds-rule--ds-rule-strong--ds-sunk--ds-switch-inset--ds-switch-knob--ds-switch-travel--ds-switch-w--ds-text-control--ds-tick-bar--ds-tick-h--ds-tick-size--ds-tick-stroke--ds-tick-w

Notes

WHY THIS IS THE ONE PLACE THE ARTWORK COULD NOT BE COPIED

The design these came from drew them as decorative markup, which is the right answer for a static mock-up. A design system may not: a styled span has no keyboard behaviour, no form value, no announced role and no indeterminate state, and every one of those has to be reinvented in JavaScript by whoever uses it.

appearance: none keeps the element and takes only its paint. The label wraps the input, so the text is part of the hit area without a for/id pair that can silently drift apart.

TWO DRAWING DECISIONS

THE TICK IS DRAWN, NOT TYPEDa glyph shifts between platforms
THE KNOB MOVES BY TRANSFORMa layout change cannot animate

The indeterminate checkbox above is set from script, because :indeterminate is a DOM state that cannot be expressed in HTML at all — the one thing on this page the specimen has to fake.