Skip to content
The Membrane Palette
Formsstable

Choice

Checkbox and radio controls drawn in the brand style, inside a clickable .mp-choice label row with optional description.

Examples

Checkboxes

Send me
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

Audience
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

Choice classes
ClassKind
.mp-choiceroot
.mp-checkboxroot
.mp-radioroot
.mp-choice__descriptionpart 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.

Choice component tokens
TokenDefaultLight · dark
--mp-choice-size1.25rem—
--mp-choice-bgvar(--color-bg-primary)#FAF6EE · #1A1B1F
--mp-choice-bordervar(--color-border-input)#7D776E
--mp-choice-border-hovervar(--color-text-secondary)#5C564E · #A39D93
--mp-choice-checkedvar(--color-action-secondary)#1B756D · #3AAFA8
--mp-choice-markvar(--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.

Choice contrast pairs
UsePairLightDarkMinimum
control boundary--mp-choice-border on --mp-choice-bg4.113.883.0
control boundary, hover--mp-choice-border-hover on --mp-choice-bg6.736.393.0
checked fill on page--mp-choice-checked on --color-bg-primary5.116.453.0
checked fill on a card--mp-choice-checked on --color-bg-secondary4.645.793.0
check / dot mark--mp-choice-mark on --mp-choice-checked5.516.453.0

Source