An ARIA modal - option 3 (old-school)
This is how a modal had to be built before the native <dialog> element was a viable option: everything native browsers now provide for free (the dialog role, aria-modal="true", Escape to close, background inertness, focus trapping) is written by hand below. Compare with option 1 and option 2.
This content should become inert while the modal is open.
A link (should not be focusable while modal is open)
Expected results:
- Focus should go to the modal - either container, heading, first focusable element inside
- The role should be announced e.g.
dialog. - The current element should be announced if not the container.
Notes
Where this differs from options 1 and 2:
role="dialog"andaria-modal="true"are set explicitly in the markup below. In options 1 and 2, the browser applies both automatically when a native<dialog>is shown modally.- Escape-to-close, background inertness, and Tab-trapping are all implemented manually in the script below. Native
<dialog>provides Escape-to-close and background inertness automatically, and does not need a hand-written Tab trap at all. - The Tab-trap logic below is written for, and only verified against, this specific dialog's content (one focusable element, the Close button). Adding further focusable content, form fields, a second button, would need the trap logic re-checked. This fragility is itself one of the main practical arguments for using native
<dialog>instead. - The
inertfallback for older browsers (seesetPageInert()below) only hides background content from assistive technology, viaaria-hidden. It does not prevent a sighted keyboard user from tabbing into that background content on a browser old enough to lackinertsupport. This is a real, known limitation of the fallback, not a complete substitute for it.