Video examples
iOS Voiceover
Windows Jaws Chrome
Windows NVDA Chrome
MacOS Voiceover Safari
Code examples
Use as much semantic HTML as possible
- This semantic HTML contains all accessibility features by default, and only requires the addition of
role="switch"
. - It uses CSS pseudo attributes to create the toggle switch indicator, no Javascript
Disabled and focusable
If it’s helpful for screenreaders to perceive a disabled toggle, use aria-disabled="true"
and prevent click events with scripting.
Disabled and not focusable
Using the disabled
attribute will prevent the input from being clickable, but will also prevent it from being focusable, making it more difficult to discover for screenreaders.
Using a <button>
as a switch
This <button>
toggle has focus and keyboard criteria built in. It requires the addition of role="switch"
and scripting to toggle aria-checked="true/false"
.
When you can’t use semantic HTML
This custom switch requires extra attributes and keyboard event listeners.
Developer notes
Name
label
text should describe the input purpose- Use
aria-describedby="hint-id"
for hints or additional descriptions aria-label="Switch purpose"
can also be used (as a last resort)
Role
- Use
role="switch"
Group
- Semantic HTML
<fieldset>
should wrap a switch group<legend>
should describe the group’s purpose- Each
<label>
must includefor="input-id"
to be associated with its input
- Custom elements
- Use
role="group"
in the palace of fieldset - Use
aria-labelledby="label-id"
to associate an element as a label aria-label="Group purpose"
can also be used if there’s no label with an ID
- Use
State
- Semantic HTML
- Use
checked
for native HTML - Use the
disabled
state for inactive switches
- Use
- Custom element
- Use
aria-checked="true/false"
to express state - Use
aria-disabled="true"
to declare inactive elements - Use
aria-readonly="true"
to declare a switch can’t be edited
- Use
Focus
- Focus must be visible