Skip to content

details, dialog, and template ​

Three built-in elements that do jobs people used to write piles of JavaScript for.

For years, if you wanted a section that expands when clicked, or a pop-up box asking "Are you sure?", you had to write it yourself in JavaScript, or pull in someone else's code. And a lot of those homemade versions were, frankly, broken for keyboard and screen reader users.

Modern HTML has these built in. They work with the keyboard, they're announced properly by screen readers, and they take a fraction of the code. Let's look at all three.

<details> and <summary>: a folded note ​

Picture a folded piece of paper with a question written on the outside. Curious? Unfold it and read the answer. Done? Fold it back up.

html
<details>
	<summary>How long does sourdough take to make?</summary>
	<p>About 24 hours from start to finish, but most of that is waiting while the dough rises. Your hands-on time is closer to 30 minutes.</p>
</details>
  • <details> is the whole folded note.
  • <summary> is the question written on the outside. It's always visible, and clicking it (or pressing Enter or Space on it) unfolds the note.
  • Everything else inside <details> is hidden until it's opened.

No JavaScript. Keyboard support, a little arrow showing whether it's open, and screen reader announcements ("collapsed," "expanded") all come built in.

Want it to start unfolded? Add the boolean open attribute: <details open>.

Accordions: only one open at a time ​

Stack a few of these and you've got an FAQ. Give them all the same name, and opening one automatically closes the others, like an accordion:

html
<details name="faq">
	<summary>Do you deliver?</summary>
	<p>Yes, within 10 km of the bakery.</p>
</details>
<details name="faq">
	<summary>Are your breads vegan?</summary>
	<p>All of our sourdough loaves are.</p>
</details>

Does that name trick feel familiar? It's the same idea as radio buttons from More Form Controls: one name, one choice at a time.

<dialog>: the waiter at your table ​

You're at a restaurant, chatting away. A waiter walks up: "Are you ready to order?" For a moment, everything else pauses. You answer the question, the waiter leaves, and you pick your conversation back up.

That's a modal dialog. It pops up over the page, and until you deal with it, the rest of the page is off-limits.

html
<dialog id="confirm-dialog">
	<h2>Remove this item?</h2>
	<p>The ceramic mug will be removed from your cart.</p>
	<form method="dialog">
		<button value="cancel">Keep it</button>
		<button value="remove">Remove</button>
	</form>
</dialog>

<button type="button" id="open-dialog">Remove from cart</button>

Opening a dialog as a modal takes one line of JavaScript (you'll understand it fully in the JavaScript track's Events lesson):

js
document.querySelector('#open-dialog').addEventListener('click', () => {
	document.querySelector('#confirm-dialog').showModal();
});

Look at everything you get for free with showModal():

  • The rest of the page is dimmed and can't be clicked or tabbed into.
  • Keyboard focus moves into the dialog automatically.
  • Pressing Escape closes it, like telling the waiter "just a minute."
  • When it closes, focus goes back to the button that opened it, so keyboard users don't get lost.

Getting all of that right by hand is genuinely hard. Many homemade pop-ups get at least one of these wrong.

And that <form method="dialog">? It's a neat trick: submitting it closes the dialog instead of sending anything to a server. The button that was pressed becomes the dialog's answer ("cancel" or "remove"), which your JavaScript can check.

Imagine baking cookies. You don't sculpt each one by hand. You have one cookie cutter, and you press out as many identical cookies as you need, then decorate each one differently.

<template> is a cookie cutter made of HTML:

html
<template id="review-template">
	<article class="review">
		<h3 class="review-author"></h3>
		<p class="review-text"></p>
	</article>
</template>

Whatever's inside a <template> is not shown on the page. Images inside it don't load, scripts inside it don't run. It just sits there, waiting. Then JavaScript can stamp out copies, fill each one in (a different reviewer's name and words), and add them to the page. Think of a product page loading 50 customer reviews: one template, 50 cookies.

This is the element you'll understand least deeply right now, and that's fine. It really only comes alive with JavaScript. What matters today is knowing it exists, so when you reach Creating and Removing Elements and need to build lots of repeated pieces, you'll remember: "Wait, HTML has a cookie cutter for this."

Try it ​

HTML

JavaScript

Preview

Try it yourself ​

  1. Open one FAQ question, then another. The first closes by itself. Now remove name='faq' from both and try again.
  2. Open the dialog, then press Escape. Open it again and press Tab a few times. Focus stays trapped inside, just like it should.
  3. Add a third FAQ question about opening hours.
  4. In the JavaScript pane, add a third review to the list. Your cookie cutter stamps it out for you.

Check your understanding ​

Inside a details element, which element holds the always-visible clickable heading?
What happens to content inside a template element when the page loads?
Which key closes a modal dialog opened with showModal()?

Up next ​

You now know every major piece of HTML. Seriously. Next, we'll talk about how professionals use all these pieces well, and the most common mistakes to avoid, in Best Practices and Common Mistakes. If you want to look back at why built-in elements beat homemade ones, Accessibility Basics makes the full case.

← iframes and Embedding
Best Practices and Common Mistakes →

Answer the quiz above correctly to continue.