Checkbox accessibility
WCAG 2.1 AA requirements
Semantics
- Renders a
<button>withrole="checkbox"andaria-checked. - Three states are announced:
true(checked),false(not checked),"mixed"(indeterminate). - The
type="button"prevents accidental form submission.
Keyboard interaction
| Key | Action |
|---|---|
Tab | Move focus to the checkbox. |
Space | Toggle the checked state. |
Standard browser behaviour for <button> — no custom key handling needed.
Label pairing
- Always pair with a
Labelcomponent linked viaid/htmlFor. This makes the label a click target and announces the field name to screen readers. - Never use a checkbox without a visible label. If a visible label is impossible, provide
aria-labelon the Checkbox directly.
Focus ring
- A 2px focus ring (
ring-ring) appears onfocus-visible. Never remove it without a replacement. - The ring uses
ring-offset-2so it's visible against both light and dark backgrounds.
Disabled state
disabledsetsaria-disabledimplicitly via the native<button>disabled attribute.- Visual treatment: reduced opacity (50%) and
cursor-not-allowed.
Audit checklist
-
role="checkbox"andaria-checkedpresent - Indeterminate state announces as
aria-checked="mixed" - Tab-able and Space toggles
- Visible focus ring on keyboard navigation
- Paired with a
LabelviahtmlFor - Disabled state is both visual and semantic