Video examples

iOS Voiceover Safari

Android Talkback Chrome

Windows Jaws Chrome

Windows NVDA Chrome

MacOS Voiceover Safari

Code examples

Use semantic HTML where possible

Browser support for <dialog> is still incomplete.

Some browsers require additional scripting. This simple example works in Chrome, but may not work correctly in all browsers such as Safari and Firefox.

<button id="showModal"
        aria-haspopup="dialog">
  Open dialog
</button>

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

Keyboard

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

Screenreader

  • The launch button should indicate a popup.
  • The modal's title is announced on launch.

Developer notes

Name

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

Role

  • For custom elements, use role="dialog"

Group

  • Upon closing, focus should return to the element that launched the dialog

State

  • Use aria-modal="true" to indicate content beneath the modal is inert.

Focus

  • Focus must be visible
  • Upon closing, focus should return to the element that launched the dialog

Documentation