Two builders come free in HTML: <dialog> for blocking decisions and the popover attribute for light toggles. Both render in the browser's top layer (above any z-index you type), close on Escape, and manage what happens to focus.
<dialog id="confirm">
<p>Delete this page for good?</p>
<button id="yes">Confirm</button>
<button id="no">Cancel</button>
</dialog>
<button popovertarget="picker">Pick</button>
<div id="picker" popover>...</div>What you delete by adopting them
- Focus trap code: showModal() traps focus while open and restores it when closed.
- Escape and backdrop wiring: the cancel/close events arrive already wired.
- The z-index arms race and its wrapper divs: ::backdrop is a selector, not an element.
Which one to pick
- A decision the reader must answer before anything else: <dialog>.showModal().
- A control that opens a small panel: popover. It is non-modal by design.
- Both: test with keyboard first, then with a screen reader; the platform work covers most, not all, edge cases.
One bug markup cannot fix for you: unsaved data behind the modal. Autosave before opening the dialog, because closing can happen in more ways than your code planned. That is the one state a hand-rolled modal usually got right and this one forgets.
