dialog-has-no-aria-modal
Web validation
role="dialog" should include aria-modal="true".When a modal dialog is open, the page behind it is meant to be inactive. The aria-modal="true" attribute tells assistive technology exactly that: everything outside the dialog is inert, so screen readers keep their reading and navigation inside the dialog.
Without aria-modal="true", a screen reader's virtual cursor can move past the end of the dialog and into the page content behind it. Users may start reading or interacting with content that is supposed to be unavailable, lose track of the dialog, and struggle to get back to it.
Note: aria-modal affects screen reader navigation only. It does not stop keyboard focus from moving to the page behind the dialog. To keep Tab inside the dialog, make the background inert or use a scripted focus trap, as described in focus-kept-within-the-modal.
Pass Patterns
Custom modal dialog with aria-modal="true"
The dialog tells assistive technology that the content behind it is inert.
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
<h2 id="dialog-title">Delete file?</h2>
<p>This action cannot be undone.</p>
<button>Cancel</button>
<button>Delete</button>
</div>Native <dialog> opened with showModal()
A native <dialog> opened with showModal() is modal by default, so assistive technology already treats the rest of the page as inert, and aria-modal is not needed.
<dialog id="confirm-dialog" aria-labelledby="confirm-title">
<h2 id="confirm-title">Delete file?</h2>
<button>Cancel</button>
<button>Delete</button>
</dialog>
<script>
document.getElementById("confirm-dialog").showModal();
</script>Fail Patterns
Custom modal dialog without aria-modal
The dialog is visually modal, but nothing tells assistive technology that the page behind it is inert, so the screen reader can read past the dialog into the background content.
<div role="dialog" aria-labelledby="dialog-title">
<h2 id="dialog-title">Delete file?</h2>
<p>This action cannot be undone.</p>
<button>Cancel</button>
<button>Delete</button>
</div>Try It Yourself
Using a screen reader
New to screen reader testing, or need a refresher?
Review this article first: Practical guides for using screen readers
- Load the page and open a screen reader.
- Open the modal dialog.
- Use the screen reader's reading commands (for example, the Down Arrow key in NVDA or JAWS browse mode, or VO + Right Arrow in VoiceOver) to read past the last element in the dialog.
Expected result: The screen reader stays within the dialog and does not read the page content behind it.
Actual result: The screen reader continues past the dialog and reads the page content behind it.
Inspecting the browser dev-tools
- Open the modal dialog.
- In your browser's dev tools, select the element with
role="dialog". - Check whether it has an
aria-modalattribute.
Expected result: The dialog has aria-modal="true", or it is a native <dialog> opened with showModal().
Actual result: The dialog has no aria-modal attribute, or its value is false.
FAQ
Why is this validation considered a best practice?
No WCAG success criterion requires aria-modal. However, when a dialog is modal, marking it with aria-modal="true" keeps screen reader users inside the dialog, matching what sighted users experience, and makes the dialog more predictable to use.
Why is this issue marked as Minor?
Screen reader users can still read and operate the dialog, but they may drift into the background content and need extra effort to find their way back. The impact is noticeable but rarely blocks a task, so the issue is rated minor.
Should every dialog have aria-modal="true"?
No. Use aria-modal="true" only when the dialog is truly modal, meaning the content behind it is unavailable while the dialog is open. On a non-modal dialog, where users can still interact with the rest of the page, aria-modal="true" would wrongly hide that content from assistive technology.
Does aria-modal keep keyboard focus inside the dialog?
No. aria-modal only informs assistive technology. Browsers do not restrict Tab based on it, so keyboard focus can still move to the page behind the dialog. To keep focus inside, make the background inert or use a focus trap. See focus-kept-within-the-modal.