Forms & Controls
Accessible Switch
A two-state on/off toggle control, distinct from a checkbox semantically.
Last verified against WCAG 2.2 and WAI-ARIA APG 1.2 on 2026-07-02.
Implementation
Wi-Fi
<span id="wifi-switch-label">Wi-Fi</span>
<!-- role="switch" (not "checkbox") makes AT announce "switch, on/off",
matching the instant-effect mental model a toggle implies, vs a
checkbox that often implies "apply on submit". A native <button>
provides focus and Enter/Space activation for free. -->
<button
type="button"
role="switch"
aria-checked="true"
aria-labelledby="wifi-switch-label"
>
<span aria-hidden="true" class="thumb"></span>
</button>Required roles, states & properties
| Element | Attribute | Why |
|---|---|---|
| Switch <button> | role="switch" | Announced as "switch," distinct from role="checkbox", communicates an instant on/off effect rather than a form value applied later. |
| Switch <button> | aria-checked | A strict boolean (true/false only, switches have no mixed state) reflecting on/off. Announced as "on"/"off" by most screen readers instead of "checked"/"not checked." |
| Switch <button> | aria-labelledby (or aria-label) | Gives the switch an accessible name, since the visible label text (e.g. "Wi-Fi") is a separate element, not the button's own text content. |
Keyboard interaction model
| Key | Behavior |
|---|---|
| Tab / Shift+Tab | Moves focus to/from the switch like any other control. |
| Space | Toggles the switch on/off. |
| Enter | Also toggles the switch, <button> fires onClick for both Enter and Space natively, so no extra handling is required. |
Focus management rules
- The switch is always a single Tab stop, there's no roving tabindex or sub-navigation involved.
- Toggling the switch never moves focus away from it, so users can flip several switches in a row with repeated Space presses.
- Changing a switch's state must never trigger an unexpected context change (e.g. navigating away or opening a dialog) per SC 3.2.2 On Input.
WCAG 2.2 success criteria mapping
| SC | Name | Level | Why it applies |
|---|---|---|---|
| 1.3.1 | Info and Relationships | A | Structure and relationships conveyed visually are also programmatically determinable. |
| 2.1.1 | Keyboard | A | All functionality is operable through a keyboard interface with no specific timing. |
| 2.5.8 | Target Size (Minimum) | AA | Pointer targets are at least 24x24 CSS pixels, unless spaced, inline, or essential. |
| 4.1.2 | Name, Role, Value | A | For all UI components, name, role, and value are programmatically determinable; states and changes are announced. |