Accessibility
For designers
Section titled “For designers”- The Modal must trap focus while it is open, keeping keyboard and assistive technology users inside the dialog.
- Focus must return to the trigger once the Modal is closed.
- The first focusable element should be the Close Button.
- The Modal must announce itself to screen readers as a dialog using the correct accessibility attributes (for example
role="dialog"andaria-modal="true"). - Content inside the slot must follow the accessibility rules of each component placed inside it.
For developers
Section titled “For developers”The <dialog> element
Section titled “The <dialog> element”Always render a modal on a <dialog> element and open it with showModal(). This gives you built-in browser behaviour that is difficult to replicate manually:
- Promotes the dialog to the top layer — no
z-indexconflicts. - Renders a
::backdroppseudo-element automatically. - Traps focus inside the dialog while it is open.
- Returns focus to the previously focused element on close.
- Closes on Escape by default.
Roles & attributes
Section titled “Roles & attributes”| Attribute | Purpose |
|---|---|
aria-labelledby | Point to the modal’s visible title so assistive technologies announce it. |
aria-describedby | Optionally point to a description paragraph for additional context. |
aria-controls | Set on the trigger button, referencing the dialog’s id. |
aria-modal="true" | Implied automatically when using showModal(). |
Inert background
Section titled “Inert background”When a modal is open the rest of the page must be unreachable. showModal() handles this for the accessibility tree, but pointer events on the underlying page can still leak through. Set document.body.inert = true while the dialog is open and reset it on close, as shown in the Modal Dialog recipe.
Keyboard interaction
Section titled “Keyboard interaction”| Key | Action |
|---|---|
| Tab / Shift+Tab | Cycles focus through focusable elements inside the dialog (focus trap is built in with showModal()). |
| Escape | Closes the dialog (built-in). Listen for the close event to run cleanup. |
Closing with a form
Section titled “Closing with a form”Wrap the dialog content in a <form method="dialog">. Any <button> inside the form that is not type="button" will close the dialog and its value will be available via dialog.returnValue. This keeps close / confirm actions accessible without custom JavaScript.
Focus Order
Section titled “Focus Order”The Modal follows a consistent focus-trap pattern across all devices:
Desktop & Portable Devices (keyboard navigation)
- Initial focus moves to the first interactive element: the Close button (always present). This ensures a predictable and accessible starting point regardless of the content inserted in the slot.
- Tab / Shift+Tab cycle through all interactive elements inside the Modal in this order:
- Close button
- Interactive elements inside the content slot (if any)
- Action buttons (horizontal or vertical set — optional)
- Link (optional)
- Focus cannot escape the Modal until it is closed.
- When closing, focus returns to the element that triggered the Modal.
Mobile & Tablet (touch + assistive tech)
- Mobile users do not navigate with a physical Tab key, but assistive technologies (VoiceOver, TalkBack, Switch Control) follow the same logical focus sequence defined for desktop.
- The focus-trap still applies:
- Screen readers move through the elements in the same order: Close → Slot content → Action buttons (optional) → Link (optional).
- Users cannot reach content outside the Modal until it is closed.
Universal rule — Closing the Modal always returns accessibility focus to the element that opened it.