Standards · ARIA

State Widget state

aria-modal

Tells assistive technology to treat the rest of the page as inert while a dialog is open. Set to "true" on role="dialog" or role="alertdialog". Does not actually make the background inert — pair with the inert attribute or a focus trap.

When to use

On a role="dialog" or role="alertdialog" element that should block interaction with the rest of the page while open. Set aria-modal="true" so the screen reader confines its virtual cursor to the dialog and announces background content as unreachable.

A modal dialog has three responsibilities:

  1. aria-modal="true" — tells assistive technology this is modal.
  2. Background inert — applied via the inert attribute on the surrounding content, or by JavaScript-managed focus trapping. Without this, keyboard users can tab out of the dialog.
  3. Initial focus — moves focus into the dialog when it opens, and restores focus to the trigger when it closes.

aria-modal alone covers the screen-reader side; it does not stop a keyboard user from tabbing past the dialog. Browser support for inferring inertness from aria-modal is inconsistent, so always combine.

The native HTML <dialog> element with .showModal() handles all three automatically. Prefer it when feasible.

How to keep it in sync

Valid values are "true" and "false". Render "true" while the dialog is open; either remove the attribute or set "false" while it is closed (typically the closed dialog is not in the DOM at all, so the attribute is moot).

aria-modal is paired with two labelling attributes:

  • aria-labelledby="<dialog-title-id>" — points at the visible heading.
  • aria-describedby="<dialog-body-id>" — optional, for a short description.

Together they give the screen reader a coherent opening announcement: “Dialog, Delete account?, This action cannot be undone.”

Common failures

  • aria-modal="true" without any focus trap — keyboard users tab into the background.
  • Using aria-modal on a non-modal popover or tooltip. Use role="dialog" only for true modal dialogs; a popover is not a dialog.
  • Missing aria-labelledby — the screen reader announces “Dialog” with no name.
  • Failing to move focus into the dialog when it opens.
  • Failing to restore focus to the original trigger when it closes.
  • Marking the background with aria-hidden="true" instead of inert — keyboard focus still escapes; only the screen-reader cursor is constrained.
  • Two simultaneously-open modals with aria-modal="true". The accessibility tree gets confused; show one at a time.

Example

<div
  role="dialog"
  aria-modal="true"
  aria-labelledby="confirm-title"
  aria-describedby="confirm-body"
>
  <h2 id="confirm-title">Delete account?</h2>
  <p id="confirm-body">This action cannot be undone.</p>

  <button type="button" autofocus>Cancel</button>
  <button type="button">Delete</button>
</div>