Dialog, details and popover

HTML · Advanced · 12 min

Native interactive elements handle focus, Escape and stacking for you, which custom modals routinely get wrong.

HTML now covers interactions that used to need a JavaScript library.

details and summary make a disclosure widget: <summary> is the always-visible toggle, the rest shows when open. No script required, keyboard accessible, searchable with find-in-page. Several <details> with the same name attribute form an exclusive accordion: opening one closes the others.

dialog is a native modal or non-modal box.

  • dialog.showModal() opens it as a modal: it's placed in the top layer above everything, the rest of the page becomes inert, focus moves inside, and Escape closes it. Style the dimmed background with ::backdrop.
  • dialog.show() opens it non-modally; dialog.close(value) closes it.
  • A <form method="dialog"> inside closes the dialog on submit and sets dialog.returnValue to the submitting button's value.

popover is an attribute that turns any element into a popup in the top layer: <div popover id="menu">. A button with popovertarget="menu" toggles it, with no JavaScript. popover (auto) popovers light-dismiss: clicking outside or pressing Escape closes them, and opening one closes other auto popovers. popover="manual" stays open until closed explicitly, for toasts.

Prefer dialog for anything that demands a response, and popover for menus, tooltips and pickers. Both avoid z-index battles because the top layer always wins.

Example

<details name="faq" open>
  <summary>What is Topolearn?</summary>
  <p>A tree of short lessons.</p>
</details>
<details name="faq">
  <summary>Is it free?</summary>
  <p>Yes, the essentials are.</p>
</details>

<button popovertarget="menu">Options</button>
<div popover id="menu">Rename · Duplicate · Delete</div>

<button id="del">Delete project</button>
<dialog id="confirm">
  <form method="dialog">
    <p>Delete this project?</p>
    <button value="cancel">Cancel</button>
    <button value="delete">Delete</button>
  </form>
</dialog>
<script>
  const dlg = document.getElementById("confirm");
  document.getElementById("del").onclick = () => dlg.showModal();
  dlg.onclose = () => console.log(dlg.returnValue); // "cancel" or "delete"
</script>

Remember

  • details/summary = disclosure with no JS; shared name = accordion
  • showModal() gives top layer, inert background, Escape to close
  • form method="dialog" closes and sets returnValue
  • popover + popovertarget = light-dismiss popups with no JS

Watch out for

  • Opening a modal with dialog.show() and wondering why the page behind stays interactive.

Check yourself

  1. What does a <form method="dialog"> inside a <dialog> do when submitted?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/dialog

Builds on

Unlocks

Nothing builds on this yet.