Accessibility
a11y/dialog-native
Build dialogs on the native <dialog> element opened with showModal() rather than a div with role="dialog".
minorstaticWCAG 2.4.3, 4.1.2 · Afe-a11y-dialog
Why
A div dialog needs a hand-written focus trap, Escape handling, a way to hide the rest of the page from screen readers, and focus return. Each is a common source of bugs. <dialog> with showModal() does all of it and is Baseline widely available.
Fix
Render <dialog>, open it with dialog.showModal() (modal) or dialog.show() (non-modal), close it with dialog.close() or a <form method="dialog">, and style the overlay with ::backdrop. Keep a component library's dialog if the project uses one; check it renders <dialog> or implements the APG pattern.
Examples
<!-- bad -->
<div class="modal" role="dialog" aria-modal="true">…</div>
<!-- good -->
<dialog aria-labelledby="t"><h2 id="t">Newsletter</h2>…</dialog>
<script type="module">document.querySelector('dialog').showModal()</script>Sources
Facts
- Id
a11y/dialog-native- Severity
- minor
- Check
- static checked in the source by
audit - Applies to
htmlangularvuesvelteastrojsx- WCAG 2.2
- 2.4.3, 4.1.2, level A
- Taught by the skill
fe-a11y-dialogDialogs and modals- Since version
- 0.1.0
Read it in the terminal
npx github:dawidolko/frontend-skills explain a11y/dialog-native