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

  1. A decision the reader must answer before anything else: <dialog>.showModal().
  2. A control that opens a small panel: popover. It is non-modal by design.
  3. 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.