Native dialog Element
debt(d5/e3/b3/t5)
Closest to 'specialist tool catches it' (d5), because detection_hints lists axe and Lighthouse — both are specialist accessibility audit tools that can flag custom div-based modals missing focus traps or the native dialog element, but neither is a default linter nor a compiler error.
Closest to 'simple parameterised fix' (e3), because the quick_fix describes replacing a DIV-based modal with the native <dialog> element — a recognisable pattern replacement within one component, not a single-line swap but not a multi-file refactor either.
Closest to 'localised tax' (b3), because applies_to is scoped to web contexts and the choice is per-modal-component. The rest of the codebase is unaffected; only the modal implementation site pays the cost of managing ARIA, focus trapping, and keyboard handling if the wrong approach is chosen.
Closest to 'notable trap' (t5), because the misconception field explicitly states developers believe native dialog is less flexible than a custom modal, leading them to build DIV-based implementations that silently miss accessibility requirements. Additionally, the common_mistakes cite using show() instead of showModal() — a same-named method with subtly different behavior that is a documented gotcha.
Also Known As
TL;DR
Explanation
The dialog element renders a modal (when opened with showModal()) or non-modal dialog (show()). Features: automatic focus trapping (Tab cycles within), backdrop pseudo-element (::backdrop for overlay styling), Escape key closes modal automatically, returnValue for form results, and correct ARIA semantics (role=dialog, aria-modal). Close with dialog.close() or a form method=dialog button. The dialog element replaced dozens of JS modal libraries — it handles all the accessibility requirements that were previously hand-coded.
Common Misconception
Why It Matters
Common Mistakes
- Using show() when a modal (focus-trapped) is needed — use showModal() for modal dialogs.
- Not styling ::backdrop — the default backdrop is transparent; add a semi-transparent background.
- Placing dialog outside the modal stack — always append dialog to document.body.
- Not calling dialog.close() on confirm/cancel buttons — dialog stays open without explicit close.
Code Examples
<!-- Custom modal — manual accessibility:
<div id="modal" role="dialog" aria-modal="true" style="display:none">
<!-- Manual focus trap needed -->
<!-- Manual Escape key handler needed -->
<!-- Manual ARIA management needed -->
<!-- 50 lines of JS for what dialog does natively -->
</div>
<!-- Native dialog — automatic accessibility:
<dialog id="confirm">
<h2>Confirm deletion?</h2>
<p>This cannot be undone.</p>
<form method="dialog">
<button value="cancel">Cancel</button>
<button value="confirm">Delete</button>
</form>
</dialog>
<button onclick="document.getElementById('confirm').showModal()">
Delete
</button>
<script>
document.getElementById('confirm').addEventListener('close', e => {
if (e.target.returnValue === 'confirm') deleteItem();
});
</script>