Choicebox

Radio semantics in a card body, for choices that need explaining.

v1.0.0·Updated Jul 8, 2026 · 10:45
Live Demo — Fully Interactive
One choice — the whole card is the target
Configuration
Selection
Media
State
Title
ProFor growing teams and shared systems.
<Choicebox checked>Pro</Choicebox>
Behavior — The Engineering Contract
PropTypeNotes
valuestringThe option's identity within its group
multiple (group)booleanCheckbox semantics instead of radio
title / descriptionstringPrimary label and supporting line
iconReactNodeOptional leading glyph tile
disabledbooleanUnselectable, opacity 0.45
↑ / ↓ · SpaceMove within the group; Space toggles

Reach for a Choicebox when each option needs a sentence of explanation. For bare options use Radio or Checkbox; for a compact known list use Dropdown.

Anatomy
ProFor growing teams.
1ControlRadio or checkbox showing the state.
2BodyTitle plus a short explaining line.
3CardThe whole surface is the hit target.
Do's and Don'ts
✓ Do
ProFor growing teams and shared systems.

Give each card a clear title and one line of why. That is the whole point.

✕ Don't
Pro

Don't drop the description. A titleless card is just a fat radio button.

✓ Do
MonthlyYearly

Keep a group to a scannable few. Three to five options, one selected.

✕ Don't
ABCDEF

Don't use choiceboxes for a dozen bare options. That wants a Dropdown.

In context: Examples
A · Plan picker
Pro — $20Per seat, billed monthly.

Pricing tiers where each option carries a price and a promise.

B · Onboarding
DesignEngineering

Role selection during onboarding, one warm card selected.

C · Framework
React

Icon-led choiceboxes for a visual set like frameworks or themes.

Measurements & Tokens
TokenValueRole
--choice-pad14pxCard padding
--choice-radius10pxCard corner
--choice-border#242428Resting hairline
--choice-on-borderrgba(255,122,0,.55)Selected border
--choice-on-fillrgba(255,122,0,.06)Selected tint
--choice-icon34px · #16171BLeading glyph tile
Code
<div role="radiogroup" aria-label="Plan">
  <button role="radio" aria-checked="true" class="o-choice is-selected">
    <span class="o-choice__mark"><span class="o-radio is-on"></span></span>
    <span class="o-choice__body">
      <span class="o-choice__title">Pro</span>
      <span class="o-choice__desc">For growing teams.</span>
    </span>
  </button>
</div>