Video examples

iOS Voiceover

Android Talkback

Windows Jaws Chrome

Windows NVDA Chrome

MacOS Voiceover Safari

Code examples

Use semantic HTML

This semantic HTML contains all accessibility features by default.

<label for="best-nato-letter">
  The best NATO letter is:
</label>
<input type="text" 
       id="best-nato-letter" 
       aria-describedby="best-nato-letter-hint">

<div class="hint" id="best-nato-letter-hint">
  Example: Alpha, Bravo, Charlie
</div>
Example: Alpha, Bravo, Charlie

Required input

<label for="second-nato-letter">
 The second NATO letter is: <span>Required</span>
</label>
<input type="text"
       id="second-nato-letter"
       aria-required="true"
       required
       value="Bravo">

Disabled but focusable input

  • There may be times that it is advantageous for the input to be disabled but still focusable
  • Fully disabled inputs are not focusable and may not be as discoverable in a form
  • Use readonly to prevent editing
<label for="first-nato-letter">
  The first NATO letter is:
</label>
<input type="text" 
       id="first-nato-letter" 
       aria-disabled="true"
       value="Alpha"
       readonly>

Fully disabled input

  • Fully disabled inputs are not focusable so may not be as discoverable in a form
<label for="suavest-nato-letter">
  The suavest NATO letter is:
</label>
<input type="text" 
       id="suavest-nato-letter"
       value="Romeo"
       disabled>

readonly input

  • Only use readonly when presenting already submitted information.
  • readonly inputs are focusable but not editable
  • VoiceOver does not describe readonly attribute, so aria-disabled was added to reinforce that it’s not editable
<label for="fourth-nato-letter">
  The fourth NATO letter is:
</label>
<input type="text"
       id="fourth-nato-letter"
       aria-readonly="true"
       aria-disabled="true"
       readonly
       value="Delta">

Email input

  • Setting type=”email” changes the keyboard for mobile app users
<label for="email">
  Email address
</label>
<input id="email"
       type="email"
       autocomplete="email"
       spellcheck="false"
       aria-describedby="hint-email">
<div class="hint" id="hint-email">
  We’ll never sell or share your information
</div>
    
We’ll never sell or share your information

Group of inputs

After the screenreader focuses on each input, it will read the group name “Enter your personal information” after the input.

<fieldset>
  <legend>
    Enter your personal information
  </legend>

  <label for="first-name">
    First name
  </label>
  <input type="text" id="first-name">

  <label for="last-name">
    Last name
  </label>
  <input type="text" id="last-name">

  <label for="username">
    Username
  </label>
  <input type="text" id="username">
</fieldset>
Enter your personal information

Developer notes

Name

  • Include for="input-id in each <label> label to associate it with the input
  • Use aria-label="Input name" as a last resort if a <label> can’t be used
  • Don’t hide the label on focus

Role

  • Identifies as a text input

Group

  • Include for="input-id in each <label> label to associate it with the input
  • Use <fieldset> and <legend> to name a group of inputs.

Focus

  • Focus must be visible