The Incredible Accessible Modal Window, Version 2

Read about Version 3.

Read the blog post about the updates to this demonstration.

Get the code on GitHub

This page demonstrates how to make a modal window as accessible as possible to assistive technology users. Modal windows are especially problematic for screen reader users. Often times the user is able to "escape" the window and interact with other parts of the page when they should not be able to. This is partially due to the way screen reader software interacts with the Web browser.

What's New In Version 2?

Version 2 builds on Version 1 and incorporates some new features and handles improvements in screen reader support.

The Accessible Modal Window in Action

To see this in action, you just need to . If the modal window works as planned, once the modal window is visible you should not be able to interact with other links on the main page like going to our main accessibility page. If you can interact with the page behind the modal window, guidance is given for how to get back to the modal window.


This example implements the following features:

  1. The page is divided into three sections:
    1. <div id="mainPage></div>
    2. <div id="modal" role="dialog"></div>
    3. <div id="modalOverlay"></div>
  2. When the modal dialog is displayed, an overlay is placed over top of the mainPage so it is
    1. visually grayed out in order to indicate you cannot interact with what is behind the window
    2. not clickable with the mouse
  3. When the modal dialog is displayed, the mainPage is marked with aria-hidden="true" to prevent screen readers from interacting with it once the modal dialog is open
  4. Keyboard access is limited to only interacting with the modal dialog once it is visible
    1. The tab key loops through all of the keyboard focusable items within the modal window
    2. This is determined programmatically through the DOM each time the tab key is pressed so you do not have to create an explicit list of focusable items within the modal window to keep track of
    3. The escape key is mapped to the function to close the modal window
    4. The enter key is mapped to the submit function of the modal window
  5. The title of the modal dialog is identified through the aria-labelledby attribute.
  6. The beginning of the modal dialog is marked with an h1
  7. There are offscreen instructions that describe the modal dialog and how to interact with it
    1. The instructions are attached through the aria-describedby attribute.
    2. In a previous version of this demonstration, the description was attached through the aria-labelledby attribute. It is more semantically correct to put the description/overview of the window in the aria-describedby attribute.
    3. JAWS, NVDA, and ChromeVox announce both the aria-labelledby and aria-describedby attributes when the modal dialog opens.
    4. VoiceOver only announces the aria-labelledby attribute, but users can still read the instructions via the virtual cursor.
    5. Orca does not announce either the aria-labelledby or aria-describedby attributes, but users can still read the title and instructions via the virtual cursor.
  8. This configuration also wraps the entire inner contents of the modal dialog with a role="document". This allows all screen reader users the ability to use their virtual cursor inside of the modal dialog. This facilitates navigating more complex modal dialogs. This is optional and only necessary if you have elements in the modal dialog that are not focusable or are not labels of focusable elements.
    • All of the screen readers except for NVDA already allow for the virtual cursor to be used in a role="dialog", however, the implementation of keyboard support and the virtual cursor in screen readers for role="dialog" is complicated. Refer to the blog post for more details.
    • Providing this functionality allows NVDA users to also have this feature.
  9. Note, there used to be a shim in place to handle a support problem in VoiceOver. In OS X 10.9 this bug has been fixed and the shim is no longer needed.
  10. Configurations Tested
    • JAWS 15.0.4203 in IE 11.0.9600.16428 in Windows 7, Service Pack 1: Passed
    • NVDA 2013.3 in Firefox 26.0 in Windows 7, Service Pack 1: Passed
    • VoiceOver in Safari 7.0 (9537.71) in OS X 10.9.0: Passed - although aria-describedby is not read automatically
    • ChromeVox 1.31.0 in Chrome 31.0.1650.63 in OS X 10.9.0: Passed
    • Orca 3.4.2 in Firefox 26.0 in Ubuntu 12.04: Partial Functionality - does not support aria-hidden and does not automatically announce the title of the window or window description