Choice
Checkbox and radio controls drawn in the brand style, inside a clickable .mp-choice label row with optional description.
Examples
Checkboxes
HTML for “Checkboxes”
<fieldset class="mp-fieldset">
<legend class="mp-fieldset__legend">Send me</legend>
<label class="mp-choice"><input class="mp-checkbox" type="checkbox" checked> New essays</label>
<label class="mp-choice">
<input class="mp-checkbox" type="checkbox">
<span>Workshop dates<span class="mp-choice__description">About once a month, never more.</span></span>
</label>
<label class="mp-choice"><input class="mp-checkbox" type="checkbox" disabled> Product updates (paused)</label>
</fieldset>
Radios
HTML for “Radios”
<fieldset class="mp-fieldset">
<legend class="mp-fieldset__legend">Audience</legend>
<label class="mp-choice"><input class="mp-radio" type="radio" name="choice-audience" checked> Educators</label>
<label class="mp-choice"><input class="mp-radio" type="radio" name="choice-audience"> Developers</label>
<label class="mp-choice"><input class="mp-radio" type="radio" name="choice-audience"> Researchers</label>
</fieldset>
Guidance
.mp-checkbox and .mp-radio restyle the native inputs — they stay real form controls, so keyboard support, form submission and validation all work for free. Wrap each one, together with its text, in <label class="mp-choice"> so the whole row is clickable.
Checked controls use the teal digital register (--color-action-secondary), keeping terracotta reserved for the one primary action on the page.
When to use
- Checkbox: independent on/off options, or multi-select from a list.
- Radio: exactly one option from a short list (2–5). Longer lists → a
<select>. - A setting that applies immediately → Switch.
Accessibility
- Group related controls in a
<fieldset>with a<legend>— the legend is announced with each option. - Indeterminate ("some selected") is set from script:
checkbox.indeterminate = true. - Under Windows High Contrast the controls revert to native rendering so the checked state stays visible.
API
| Class | Kind |
|---|---|
.mp-choice | root |
.mp-checkbox | root |
.mp-radio | root |
.mp-choice__description | part of .mp-choice |
States styled: :checked :disabled :focus-visible :hover :indeterminate [aria-invalid="true"]. Set the native attribute or ARIA state; there are no state classes.
| Token | Default | Light · dark |
|---|---|---|
--mp-choice-size | 1.25rem | — |
--mp-choice-bg | var(--color-bg-primary) | #FAF6EE · #1A1B1F |
--mp-choice-border | var(--color-border-input) | #7D776E |
--mp-choice-border-hover | var(--color-text-secondary) | #5C564E · #A39D93 |
--mp-choice-checked | var(--color-action-secondary) | #1B756D · #3AAFA8 |
--mp-choice-mark | var(--color-text-on-accent) | #FFFFFF · #1A1B1F |
Design tokens consumed: --border-width-medium --color-action-secondary --color-bg-primary --color-border-input --color-error --color-text-on-accent --color-text-primary --color-text-secondary --focus-ring --focus-ring-offset --font-sans --leading-body-lg --leading-small --radius-full --radius-sm --space-2 --space-3 --state-disabled-opacity --text-body --text-small --transition-fast --transition-state
Verified contrast
The build measures each pair for the defaults and for every tone, variant and state that reassigns a token, over page and card surfaces. The ratios below are the worst case in each mode; a pair below its minimum stops the build.
| Use | Pair | Light | Dark | Minimum |
|---|---|---|---|---|
| control boundary | --mp-choice-border on --mp-choice-bg | 4.11 | 3.88 | 3.0 |
| control boundary, hover | --mp-choice-border-hover on --mp-choice-bg | 6.73 | 6.39 | 3.0 |
| checked fill on page | --mp-choice-checked on --color-bg-primary | 5.11 | 6.45 | 3.0 |
| checked fill on a card | --mp-choice-checked on --color-bg-secondary | 4.64 | 5.79 | 3.0 |
| check / dot mark | --mp-choice-mark on --mp-choice-checked | 5.51 | 6.45 | 3.0 |