Switch

A switch is a control with two mutually exclusive states — on or off — that takes effect immediately, like a physical light switch. It carries role="switch" and an aria-checked value of true or false, and it always has an accessible name so a screen-reader user hears Wi-Fi, switch, on rather than an unlabelled toggle.

Prefer a native control when one fits: an HTML <input type="checkbox"> already exposes a checked state to assistive technology, and styling it as a switch (optionally with role="switch") is the most robust route inside forms. Build the button-based switch below when you need an immediate setting that is not submitted with a form. It follows the WAI-ARIA Authoring Practices switch pattern; switch.js enhances authored markup, and with scripting off the control is still a labelled button.

Live demo

Move focus to the switch with Tab, then press Space or Enter to flip it. The state changes in three independent ways — the thumb slides, the track fills, and the word beside it reads On or Off — so it never depends on colour alone.

When to use

Reach for a switch — or a checkbox?

  • Use a switch for an on/off setting that applies immediately, like Dark mode or Wi-Fi.
  • Use a checkbox for a selection — agreeing to terms, picking items, or anything submitted later with a form.
  • Prefer native HTML: a styled <input type="checkbox"> gives you the checked state, keyboard, and label wiring for free.
  • Whatever you choose, the control must keep a real, visible accessible name — the visible text label, not a placeholder or icon alone.

Markup

Author the button with its role, state, and label in place, then let switch.js toggle aria-checked on activation. Because it is a real <button>, Space and Enter fire a click natively — no extra key handling is needed.

switch.html
<button type="button" class="ewa-switch" role="switch"
        aria-checked="false" data-switch>
  <span class="ewa-switch__text">Email notifications</span>
  <span class="ewa-switch__track" aria-hidden="true">
    <span class="ewa-switch__thumb"></span>
  </span>
  <span class="ewa-switch__state" data-switch-state aria-hidden="true">Off</span>
</button>

Keyboard interactions

The switch is a single focusable control. Because it is a button, the platform handles activation keys for you — there is no custom key handling to maintain.

Keyboard interactions
Key Action
Tab Moves focus to the switch (and away again to the next control).
Space Toggles the switch on or off.
Enter Toggles the switch on or off.

ARIA roles, states, and properties

The button takes the switch role and reports its on/off state through aria-checked. Its accessible name comes from the visible text inside the button, so the label and the control can never drift apart.

ARIA attributes and where they live
Attribute On Purpose
role="switch" Button Identifies the control as an on/off switch rather than a plain button.
aria-checked="true" Button The switch is on. Set when the setting is active.
aria-checked="false" Button The switch is off. The attribute is always present, never omitted.
Accessible name Button The visible label text inside the button names the switch (e.g. Email notifications); no separate aria-label needed.
aria-hidden="true" Track & state word Hides the purely visual track, thumb, and duplicated On/Off word from AT — the role and state already convey on/off.

Common mistakes

Pitfalls to avoid

  • Using a switch where a checkbox belongs. A switch is for an immediate on/off setting; a checkbox is for selection, usually submitted with a form. Picking the wrong one mismatches the user’s mental model and the announced role.
  • Relying on colour alone for the state. A green-vs-grey track is invisible to many users — keep the accessible name plus an on/off cue beyond hue, such as the thumb position and an On/Off word.
  • Dropping the accessible name. An icon or bare track is not a label; the switch needs visible text that names what it controls.
  • Omitting aria-checked when off. The attribute must always be present as true or false, never absent.
  • Moving focus on toggle. Flipping the switch must change only the state; focus stays on the control so keyboard users keep their place.