Video examples

iOS Voiceover

Android Talkback

Windows Jaws Chrome

MacOS Voiceover Safari

Variations

(Spoiler alert: These all have the same rules.)

Required attributes

Do not use the Popover API

The Popover API cannot be used to launch a dialog modal. The Popover element will not have the same semantics or built in features of a JS launched using modal.showModal();

Launch button

  • Should be a button, not a link
  • Upon closing, focus must return to the button that launched the dialog
  • Do not usearia-haspopup. This attribute has very low and support and unpredictable output across screen readers.

Name

  • The modal window has a logical descriptive name from either:
    • aria-label="Modal title" or
    • aria-labelledby="heading-id" pointing to an <h2> as a title

Role

  • Use role="dialog" so the screen reader can identify this as a dialog or modal

Group

  • Upon closing, focus must return to the button that launched the dialog

State

  • Use aria-modal="true" to indicate content beneath the modal is inert and that the screen reader must not browse outside the dialog.

Focus

  • Use tabindex="-1" to make the modal itself targetable for focus
    • This is a helpful pattern because not every modal has a dismiss button (ex: Alert options for being signed out if user is inactive)
  • Upon closing, focus must return to the button that launched the dialog

Screenreader differences

  • NVDA
    • By default, NVDA may read the entire modal upon launch. This is expected behavior.
  • iOS Voiceover
    • Voiceover will place focus on the first focusable control, no matter what JS targets for focus

Code examples

Dialog using JS (Do NOT use Popover API)

<button id="showModal">
  Things you should know
</button>

<dialog role="dialog"
        id="modal"
        tabindex="-1"
        aria-modal="true"
        aria-labelledby="dialog-title">
  <button type="button"
          id="closeModal"
          class="close">
    <span class="hidden">Close</span>
  </button>
  <div class="dialog-content">
    <h2 id="dialog-title" class="h-bravo">
      Things you should know
    </h2>
    <h3>Keyboard</h3>
    <ul>
      <li>Focus must not enter the rest of the page.</li>
      <li>The escape key must close the modal.</li>
    </ul>
    <h3>Screenreader</h3>
    <ul>
      <li>The modal's title is announced on launch.</li>
      <li>The screen reader cannot read content behind the dialog.</li>
    </ul>
    <button type="submit">
      Continue
    </button>
  </section>
</dialog>

Things you should know

Keyboard

  • Focus must not enter the rest of the page.
  • The escape key must close the modal.

Screenreader

  • The modal's title is announced on launch.
  • The screen reader cannot read content behind the dialog.

Documentation

Related dialog modal popup entries