Skip to content

Accessibility

The toggle follows the WAI-ARIA Switch pattern — a single control that flips a setting between on and off with immediate effect — and meets WCAG 2.1 AA. Built on a native <input type="checkbox">, an accessible toggle is reachable and operable from the keyboard, carries a label that names the setting it controls, and reports its on / off state to assistive technology — so the setting is clear whether the user is looking at it, listening to it, or tabbing through it.

  • Every state (rested, hover, pressed, disabled, focus) must maintain accessible contrast on every supported surface, in both the on and off positions. Source: WCAG 1.4.3 Contrast (Minimum).
  • The on / off state must never rely on colour alone — pair the track’s colour change with the thumb’s position and the icon inside it, so the state survives for colour-blind users. Source: WCAG 1.4.1 Use of Color.
  • Focus styles must stay visible, meet contrast requirements on every supported surface, and be clearly distinguishable from hover. Source: WCAG 2.4.7 Focus Visible.
  • Use semantic colour tokens (e.g. foreground/neutral/default) rather than fixed values, so the component adapts correctly across themes and surfaces.

Build on a native <input type="checkbox"> and never recreate the control from <div> or <span> — the native element brings the role, state, and keyboard operability that assistive technology relies on, and it is what the styleguide’s CSS targets. role="switch" layers on top of that input rather than replacing it; the Switch card below weighs what it buys and what it costs. A toggle applies its change immediately, so don’t pair it with a Save step that implies the setting is pending. The whole control is a single tab stop — focus lands on the input, and the label is associated with it rather than being a stop of its own. The per-element roles, names, and states are in the Labelling elements section below.

Key Action
Tab / Shift + Tab Move focus to the next / previous control
Space Toggle the focused switch between on and off

The switch on its own is a small target — around 24 px tall, which is the floor rather than a comfortable margin. Its label counts as part of the same target, because clicking or tapping the text activates the switch, so keep the label visible and give the row enough height that the two together clear the minimum with room to spare. Source: WCAG 2.5.8 Target Size (Minimum).

Give every element the role, name, and state assistive technology needs.

Switch

A native <input type="checkbox"> already exposes a checkable role and its on / off value, so a toggle is accessible with no ARIA at all. Adding role="switch" changes the announcement from “checked” to “on” / “off”, which matches what the control looks like and what it does; the native checked property still carries the value and the role maps it to aria-checked for you. What it costs is the indeterminate state — a switch admits only on and off, so a control that needs “partially on” has to stay a plain checkbox. Convey a non-interactive switch with the native disabled attribute, which also removes it from the tab order. Don’t move state to aria-* when the native attribute already carries it.

Label

The toggle takes its accessible name from the associated <label>, wired with for/id or by wrapping the input. Keep the label visible and self-describing, and phrase it as the setting being controlled (“Notifications”) rather than an action — never leave the name to a title or placeholder, and never replace it with an icon-only control.

Supporting and error text

The is-error class is a visual cue only, and so is the same treatment the styleguide applies on its own to an :invalid input. Pair either with aria-invalid="true" and connect the message to the input with aria-describedby, so the failure is announced after the label and conveyed to assistive technology rather than by colour alone. The error styling steps aside while the switch has keyboard focus, so the focus ring stays legible — the announced state doesn’t change with it.

Source: WCAG 4.1.2 Name, Role, Value.