The quiet power of the <dialog> element
Sam Lindqvist
·
·
6 min read
For years, building a modal meant reaching for a library or writing two hundred lines of focus-trapping code. Today the browser does almost all of it for you, and most teams still have not noticed.
What you get for free
Calling showModal() on a <dialog> element gives you a surprising amount of behaviour out of the box:
- The rest of the page becomes inert, so focus and screen readers stay inside.
- Esc closes it, and focus returns to the element that opened it.
- It renders in the top layer, so
z-indexbattles are over. - A
::backdroppseudo-element you can style however you like.
const dialog = document.querySelector('dialog');
openButton.addEventListener('click', () => dialog.showModal());
dialog.addEventListener('close', () => console.log(dialog.returnValue));
The parts you still own
The element is not magic. You still need a visible heading, a clear way to close it, and sensible initial focus. Closing on a backdrop click is not built in either, though it takes three lines to add.
Reach for the platform first. Add code only for the gap between what HTML does and what your users need.
The command palette on this site (press Ctrl K) is a plain <dialog> with a search field and a list. It is about eighty lines of JavaScript, and most of those are for filtering.