Purpose
Checkboxes allow users to make binary selections, either individually or as part of a group. The indeterminate state is used for “select all” controls where a subset of children is selected.
Usage Guidance
- Use native
<input type="checkbox">whenever possible - Group related checkboxes with
<fieldset>and<legend> - Label every checkbox with an associated
<label>element - Use indeterminate state only for “select all” scenarios
Accessibility Considerations
- Native
<input type="checkbox">provides keyboard support and state announcement automatically - The
<label>element must be explicitly associated (viafor/id) or wrapping the input indeterminatestate must be set via JavaScript (checkbox.indeterminate = true)—there is no HTML attribute for it
Keyboard Support
| Key | Action |
|---|---|
Tab / Shift+Tab |
Move focus to/from checkbox |
Space |
Toggle checked state |
Screen Reader Behavior
Screen readers announce “checkbox, checked/unchecked/mixed” and the label text. The indeterminate state is announced as “mixed” by most screen readers.
ARIA Requirements
- Native HTML checkboxes require no ARIA
- Custom checkboxes require
role="checkbox"witharia-checked="true|false|mixed" - Group label requires
aria-labelledbypointing to the group heading or use<fieldset>/<legend>
Common Mistakes
- Custom checkboxes without keyboard support
- Missing
<label>association (usingplaceholderinstead) - Not updating
aria-checkedon state change for custom controls - Forgetting
aria-checked="mixed"for indeterminate state
Live Example
Code Example
<fieldset>
<legend>Select audit scope:</legend>
<label>
<input type="checkbox" name="scope" value="web" checked>
Public-facing website
</label>
<label>
<input type="checkbox" name="scope" value="mobile">
Mobile application
</label>
</fieldset>
<!-- Indeterminate state requires JavaScript -->
<script>
document.getElementById('select-all').indeterminate = true;
</script>