Video examples

iOS Voiceover Safari

Android Talkback Chrome

Windows Jaws Chrome

Windows NVDA Chrome

MacOS Voiceover Safari

Code examples

Use semantic HTML

This semantic HTML contains all accessibility features by default.

  <legend>Choose your favorite NATO letters:</legend>

  <input type="checkbox" id="alphaCheckbox">
  <label for="alphaCheckbox">Alpha</label>

  <input type="checkbox" id="bravoCheckbox">
  <label for="bravoCheckbox">Bravo</label>

  <input type="checkbox" id="charlieCheckbox" checked>
  <label for="charlieCheckbox">Charlie</label>
Choose your favorite NATO letters:

When you can’t use semantic HTML

This custom checkbox requires extra attributes and event listeners.

<div role="checkbox" tabindex="0" aria-checked="true">

Speciality checkboxes

Sometimes a design may call for a card type checkbox.

  • Its core should still be a semantic checkbox input
  • Use aria-describedby to read extra content after the the name, role and state
<ul class="cards">
  <li class="card interactive">
    <input type="checkbox"
           aria-describedby="descriptionDelta" >
    <label for="deltaCheckboxCard">
    <div class="extended-description"
      Delta (prounounced: <strong>dell</strong>-tah)
      is the fourth letter of the NATO alphabet.
  <li class="card interactive">
    <input type="checkbox"
           aria-describedby="descriptionEcho" >
    <label for="echoCheckboxCard">Echo</label>
    <div class="extended-description"
      Echo (prounounced: <strong>eck</strong>-oh)
      is the fifth letter of the NATO alphabet.
  • Delta (prounounced: dell-tah) is the fourth letter of the NATO alphabet.
  • Echo (prounounced: eck-oh) is the fifth letter of the NATO alphabet.

Developer notes


  • label text should describe the checkbox input.
  • Use aria-describedby="hint-id" for hints or additional descriptions
  • aria-label="Checkbox input purpose" can also be used (as a last resort)


  • By default, semantic HTML checkbox inputs identify as a checkbox
  • Use role="checkbox" for custom elements


  • Semantic HTML
    • <fieldset> should wrap a checkbox group
    • <legend> should describe the group’s purpose
    • Each <label> must include for="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


  • Semantic HTML
    • Use checked for native HTML
    • Use the disabled state for inactive checkboxes
  • Custom element
    • Use aria-checked="true/false" to express state
    • Use aria-disabled="true" to declare inactive elements


  • Focus must be visible
  • Custom elements will require keyboard event listeners and roving tabindex