Disclosure widgets and dialogs
Some parts of an interface are not needed all the time: an answer to a question, order details, a confirmation window. Such elements used to be written entirely in JavaScript. Today HTML has ready-made tags that open, close and work with the keyboard on their own.
A disclosure block
<details> hides its content, and <summary> is the visible heading you click:
<details>
<summary>How long does delivery take?</summary>
<p>One day within the city, up to five days nationwide.</p>
</details>Click the question — the answer appears; click again — it hides. The browser draws the triangle on the left itself.
Open from the start
The boolean open attribute shows the block expanded from the start. Several blocks in a row become a list of questions and answers:
<details open>
<summary>Can I return an item?</summary>
<p>Yes, within 30 days.</p>
</details>
<details>
<summary>Is there in-store pickup?</summary>
<p>Yes, from the coffee shop on Market Street.</p>
</details>An accordion
If several <details> share the same name attribute, only one of them can be open: opening another closes the previous one. Such a widget is called an accordion:
<details name="faq" open>
<summary>Payment</summary>
<p>By card or in cash.</p>
</details>
<details name="faq">
<summary>Delivery</summary>
<p>By courier or to a pickup point.</p>
</details>The name attribute on <details> arrived in browsers in 2024. An older browser ignores it, and the blocks open independently.
A modal window
<dialog> is a dialog window. A modal window appears on top of the page and blocks it until it is closed. It is opened from JavaScript with the showModal() method:
<style>
body { min-height: 200px; } /* room for the window in the preview */
</style>
<button onclick="document.querySelector('#hello').showModal()">Open the window</button>
<dialog id="hello">
<p>Hello! This is a modal window.</p>
<form method="dialog">
<button>Close</button>
</form>
</dialog>The window sits in the centre, and a semi-transparent backdrop covers the page below. You can close it with the button or the Esc key.
Closing with a form
A form with method="dialog" inside a <dialog> sends nothing to a server — it simply closes the window. This is handy for confirmations:
<style>
body { min-height: 200px; } /* room for the window in the preview */
</style>
<button onclick="document.querySelector('#confirm').showModal()">Delete order</button>
<dialog id="confirm">
<p>Delete order #42?</p>
<form method="dialog">
<button value="no">Cancel</button>
<button value="yes">Delete</button>
</form>
</dialog>The value of the pressed button is stored in the window's returnValue property — a script reads the user's answer from it.
A popup without JavaScript
The popover attribute turns any element into a popup, and a button with popovertarget opens and closes it — without a single line of code:
<style>
body { min-height: 200px; } /* room for the window in the preview */
</style>
<button popovertarget="tip">What is a flat white?</button>
<div id="tip" popover>
A flat white is espresso with a thin layer of steamed milk.
</div>Clicking outside the block or pressing Esc closes it. The popover attribute has been supported in all major browsers since 2024. How to animate opening and closing smoothly is shown in the lesson "Entry and exit animations".
Common mistake
<dialog> also has an open attribute, but a window opened with it is not modal: it sits right in the page flow, without a backdrop, and Esc does not close it:
<dialog open>
<p>I am opened with the open attribute — this is not a modal window.</p>
</dialog>
<p>The page text stays accessible.</p>For a real modal window, call showModal().