Complete HTML Course Module 12: Advanced: Modern HTML Features and Performance

Built-in Interactive Elements: details, dialog and popover

  • Beginner
  • Lesson 12.3
  • 5 min read
  • 53 of 69 in the course

In short

Modern HTML has interactive elements that work without (or with very little) JavaScript. In this lesson you will build an accordion with details, a modal with dialog, a popover menu, and progress bars with progress and meter.

Modern HTML has interactive elements that work without (or with very little) JavaScript. In this lesson you will build an accordion with details, a modal with dialog, a popover menu, and progress bars with progress and meter.

How to make an accordion with details and summary

An accordion is a list of sections that open and close when you click their titles, like an FAQ. The <details> element creates one section, and <summary> is the clickable title. Everything else inside <details> is hidden until the user opens it.

<h2>Shipping questions</h2>

<details name="shipping-faq">
  <summary>How long does delivery take?</summary>
  <p>Orders arrive in 2–4 working days within the EU.</p>
</details>

<details name="shipping-faq">
  <summary>Can I return my order?</summary>
  <p>Yes. You have 30 days to return any item for free.</p>
</details>

<details name="shipping-faq" open>
  <summary>Do you ship worldwide?</summary>
  <p>We ship to 45 countries. You will see the price at checkout.</p>
</details>

You see three questions with small triangles. Click a question and its answer appears. The open attribute makes the last one open when the page loads. Because all three share the same name, only one can be open at a time: opening one closes the others. Remove name if you want several open at once. It works with the keyboard and screen readers, and you wrote zero JavaScript.

Tip: Browsers can search inside closed <details> elements. If a user presses Ctrl + F and searches for "return", the matching section opens automatically.

How to make a modal dialog with the dialog element

A modal is a box that appears on top of the page and blocks the rest until you close it, like "Are you sure you want to delete this?". The <dialog> element does the hard work for you: it puts the box on top, makes the rest of the page unusable while open, moves focus inside, and closes with the Escape key.

<button type="button" id="open-delete">Delete account</button>

<dialog id="delete-dialog" aria-labelledby="delete-title">
  <h2 id="delete-title">Delete your account?</h2>
  <p>This removes all your projects. You cannot undo this.</p>
  <form method="dialog">
    <button value="cancel">Cancel</button>
    <button value="delete">Yes, delete</button>
  </form>
</dialog>

<script>
  document.getElementById("open-delete").addEventListener("click", () => document.getElementById("delete-dialog").showModal());
</script>

Click "Delete account" and the dialog appears in the centre with a dark backdrop behind it. The one line of JavaScript calls showModal(). The special method="dialog" on the form means: "Don't send this form to a server. Just close the dialog." Both buttons close it, and JavaScript can read which one was clicked from the dialog's returnValue.

Note: In the newest browsers you can also open a dialog with no JavaScript at all: <button commandfor="delete-dialog" command="show-modal">. This is part of a new feature called invoker commands. Check current support before you rely on it.

The popover attribute: menus and tooltips with no JavaScript

A popover is content that appears on top of the page when you click a button, but does not block the page like a modal does. Good examples are a small menu, a help bubble or a notification panel. Add the popover attribute to any element, and connect a button to it with popovertarget.

<button type="button" popovertarget="account-menu">My account</button>

<div id="account-menu" popover>
  <ul>
    <li><a href="/profile">Profile</a></li>
    <li><a href="/orders">My orders</a></li>
    <li><a href="/logout">Log out</a></li>
  </ul>
</div>

<button type="button" popovertarget="help-tip">What is a CVC code?</button>
<p id="help-tip" popover>The 3 digits on the back of your card.</p>

Click "My account" and the menu appears on top of everything. Click outside it or press Escape and it closes. This is called light dismiss. Only one normal popover is open at a time. The browser handles the keyboard and tells screen readers whether the popover is expanded. You can also use popovertargetaction="show", "hide" or "toggle" (the default) on the button. Where exactly the popover appears on screen is a job for CSS.

Show progress with progress and meter

These two elements look similar but mean different things.

  • <progress> shows how far a task has got, like an upload. Without a value, it shows an "in progress, unknown time" animation.
  • <meter> shows a measurement inside a known range, like disk space or a password strength score. With low, high and optimum, the browser colours it green, yellow or red.
<label for="upload">Uploading photo:</label>
<progress id="upload" value="65" max="100">65%</progress>

<label for="loading">Loading:</label>
<progress id="loading">Please wait…</progress>

<label for="storage">Storage used:</label>
<meter id="storage" value="8.2" min="0" max="10" low="6" high="9" optimum="2">8.2 GB of 10 GB</meter>

You see an upload bar two-thirds full, an animated loading bar, and a storage bar. The storage bar is in the "warning" zone because 8.2 is above low and the best value (optimum) is low. The text inside each element is a fallback, and the labels give them accessible names.

Practice exercise

Build a "Help" page with: an FAQ accordion of four questions where only one can be open at a time, a popover that explains a difficult word, and a "Contact support" button that opens a <dialog> containing a small form with a "Close" button.

Hint: The close button needs to be inside a <form method="dialog">. Give each <details> the same name value.

Key takeaways

  • <details> and <summary> make accessible accordions, and a shared name allows only one open.
  • <dialog> with showModal() creates a real modal with focus handling and Escape to close.
  • <form method="dialog"> closes a dialog without sending data.
  • The popover attribute plus popovertarget creates menus and tips with no JavaScript.
  • Use <progress> for task progress and <meter> for a value in a known range.