Skip to content

Toggle group

A toggle group is a cluster of toggle buttons where any number can be pressed at once — built on native checkboxes, so the pressed state, multi-selection, and form submission are all native. CSS-only, no JavaScript. It’s the many-of-N sibling of the single-select segmented control.

Each option is a <label class="re-toggle-group__option"> wrapping a <input type="checkbox"> (its own name/value) and a visible <span>. The pressed set submits natively — no hidden inputs.

Live example
<fieldset class="re-toggle-group" aria-label="Text formatting">
  <label class="re-toggle-group__option">
    <input type="checkbox" name="format" value="bold" checked />
    <span>Bold</span>
  </label>
  <label class="re-toggle-group__option">
    <input type="checkbox" name="format" value="italic" checked />
    <span>Italic</span>
  </label>
  <label class="re-toggle-group__option">
    <input type="checkbox" name="format" value="underline" />
    <span>Underline</span>
  </label>
</fieldset>

Give an icon-only <input> an aria-label, and mark the glyph aria-hidden="true" / focusable="false".

Live example
<fieldset class="re-toggle-group" aria-label="Text alignment">
  <label class="re-toggle-group__option">
    <input type="checkbox" name="align" value="left" aria-label="Align left" checked />
    <span>
      <svg
        viewBox="0 0 24 24"
        width="18"
        height="18"
        fill="none"
        stroke="currentColor"
        stroke-width="1.5"
        stroke-linecap="round"
        aria-hidden="true"
      >
        <line x1="4" y1="7" x2="20" y2="7" />
        <line x1="4" y1="12" x2="14" y2="12" />
        <line x1="4" y1="17" x2="17" y2="17" />
      </svg>
    </span>
  </label>
  <label class="re-toggle-group__option">
    <input type="checkbox" name="align" value="center" aria-label="Align center" />
    <span>
      <svg
        viewBox="0 0 24 24"
        width="18"
        height="18"
        fill="none"
        stroke="currentColor"
        stroke-width="1.5"
        stroke-linecap="round"
        aria-hidden="true"
      >
        <line x1="4" y1="7" x2="20" y2="7" />
        <line x1="7" y1="12" x2="17" y2="12" />
        <line x1="6" y1="17" x2="18" y2="17" />
      </svg>
    </span>
  </label>
  <label class="re-toggle-group__option">
    <input type="checkbox" name="align" value="right" aria-label="Align right" />
    <span>
      <svg
        viewBox="0 0 24 24"
        width="18"
        height="18"
        fill="none"
        stroke="currentColor"
        stroke-width="1.5"
        stroke-linecap="round"
        aria-hidden="true"
      >
        <line x1="4" y1="7" x2="20" y2="7" />
        <line x1="10" y1="12" x2="20" y2="12" />
        <line x1="7" y1="17" x2="20" y2="17" />
      </svg>
    </span>
  </label>
</fieldset>

data-size="sm" and data-size="lg" adjust padding and type.

Live example
<div class="row">
  <fieldset class="re-toggle-group" data-size="sm" aria-label="Days (small)">
    <label class="re-toggle-group__option">
      <input type="checkbox" name="day-sm" value="mon" checked />
      <span>Mon</span>
    </label>
    <label class="re-toggle-group__option">
      <input type="checkbox" name="day-sm" value="tue" />
      <span>Tue</span>
    </label>
    <label class="re-toggle-group__option">
      <input type="checkbox" name="day-sm" value="wed" checked />
      <span>Wed</span>
    </label>
  </fieldset>

  <fieldset class="re-toggle-group" data-size="lg" aria-label="Days (large)">
    <label class="re-toggle-group__option">
      <input type="checkbox" name="day-lg" value="mon" checked />
      <span>Mon</span>
    </label>
    <label class="re-toggle-group__option">
      <input type="checkbox" name="day-lg" value="tue" />
      <span>Tue</span>
    </label>
    <label class="re-toggle-group__option">
      <input type="checkbox" name="day-lg" value="wed" checked />
      <span>Wed</span>
    </label>
  </fieldset>
</div>

A disabled checkbox renders a muted, non-interactive member.

Live example
<fieldset class="re-toggle-group" aria-label="Layout">
  <label class="re-toggle-group__option">
    <input type="checkbox" name="layout" value="list" checked />
    <span>List</span>
  </label>
  <label class="re-toggle-group__option">
    <input type="checkbox" name="layout" value="grid" />
    <span>Grid</span>
  </label>
  <label class="re-toggle-group__option">
    <input type="checkbox" name="layout" value="map" disabled />
    <span>Map</span>
  </label>
</fieldset>
NeedUse
Many of N, pressed stateToggle group (this)
One of NSegmented control
Stateless joined actionsButton group
  • Native multi-select — each option is a real <input type="checkbox">, so the pressed state is announced by assistive tech (“checked”) with no aria-pressed bookkeeping, and the selected values submit with the form.
  • Group name — give the <fieldset> an aria-label (or a <legend>) so the cluster is announced as a named group.
  • Icon-only options — the <span> has no text, so the accessible name must come from an aria-label on the <input>; keep the <svg> aria-hidden="true" and focusable="false".
  • Pressed survives forced colors — the accent fill flattens under Windows High Contrast, so pressed members are re-marked with the system Highlight colour; the on/off distinction is never carried by colour alone.

See the accessibility guide for the project-wide stance.