Interface Recommended
Build modal dialogs with dialog
Build modal dialogs with the <dialog> element and showModal(), never with a styled div and your own focus code.
How to do it
Open the dialog with showModal(), or with command="show-modal" on the button in newer browsers. The browser then makes the rest of the page inert and closes the dialog on Escape. Close it with a <form method="dialog"> button. Add closedby="any" for closing on an outside click where browsers support it. Use a popover instead for menus that don't block the page.
Example
<button commandfor="confirm" command="show-modal">Delete order</button>
<dialog id="confirm" closedby="any" aria-labelledby="confirm-title">
<h2 id="confirm-title">Delete this order?</h2>
<form method="dialog">
<button value="cancel">Keep it</button>
<button value="delete">Delete</button>
</form>
</dialog>
const dialog = document.querySelector('#confirm');
dialog.addEventListener('close', () => {
if (dialog.returnValue === 'delete') deleteOrder();
});
How to check
Open the dialog with the keyboard. Tab never reaches the page behind it, Escape closes it, and focus returns to the button that opened it.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers website playbook: https://agentwranglers.se/playbook/website/interface/dialog-element.