Close Other Details Elements When One Opens (HTML Accordion)

Quick Summary
- Give every details element in the group the same name attribute and the browser keeps only one open, with no JavaScript.
- The name attribute works in Chrome and Edge 120, Firefox 130 and Safari 17.2 and later, and in WordPress the Details block has a Name attribute field.
- For older browsers, a script that listens for the toggle event closes the others however an item opens: click, keyboard, script or anchor link.
To close the other <details> elements when one is opened, give every <details> in the group the same name attribute. The browser then treats them as an exclusive accordion: opening one closes the others, with no JavaScript. Chrome and Edge 120, Firefox 130 and Safari 17.2 and later support it. For older browsers, add a short script that listens for the toggle event and closes the rest.
The HTML <details> and <summary> elements give you collapsible sections without any JavaScript. Without a name, each one opens and closes on its own, so several can be open at the same time.
How does the name attribute make an accordion?
Each <details> element holds a <summary>, the clickable title, followed by the content that shows when it’s open. Add the same name to every element in the group:
<div class="faq">
<details name="faq">
<summary>1</summary>
Demo 1
</details>
<details name="faq">
<summary>2</summary>
Demo 2
</details>
<details name="faq">
<summary>3</summary>
Demo 3
</details>
</div>The wrapper div isn’t needed for the name attribute; it’s there for styling and for the fallback script below.
In a test in headless Chrome 153, the group behaved like this:
- Opening an item, with a click or with Enter or Space on its summary, closed the one that was open.
- Clicking the open item’s summary closed it, leaving all of them closed. The attribute allows at most one open item; it doesn’t force one to stay open.
- Opening an item from a script, with
details.open = true, and following a link to an anchor inside a closed item also closed the others. - When the HTML gave the
openattribute to two items, only the first was open after the page loaded.
The group is every <details> on the page with the same name. MDN notes that they don’t have to sit next to each other, so give each accordion on a page its own name, such as faq and shipping.
Which browsers support it?
According to MDN’s browser compatibility data, the name attribute on <details> works in Chrome and Edge 120, Firefox 130, and Safari 17.2 on Mac and iPhone. It has been Baseline, meaning supported in all major browsers, since September 2024. An older browser ignores the attribute and lets several items be open at once, so nothing breaks; if you need the accordion behavior there too, add the fallback below.
Can you set it in the WordPress block editor?
Yes. In WordPress 7.1, the Details block has a Name attribute field in the Advanced panel of its settings. Give every Details block in the group the same name, and the block saves it on the <details> element. The separate Accordion block has an Auto-close setting for the same effect, but it doesn’t use <details> elements.
How do you close the other details elements with JavaScript?
This script does the same job in browsers that don’t support the name attribute. Load it after the HTML, for example just before </body>, so the elements exist when it runs:
// Close the other details elements in .faq when one of them opens.
// Only runs in browsers that don't support the name attribute on details.
if (!("name" in HTMLDetailsElement.prototype)) {
const details = document.querySelectorAll(".faq details");
details.forEach((targetDetail) => {
targetDetail.addEventListener("toggle", () => {
// Ignore the event when targetDetail was closed.
if (!targetDetail.open) {
return;
}
// Close all the details that are not targetDetail.
details.forEach((detail) => {
if (detail !== targetDetail) {
detail.removeAttribute("open");
}
});
});
});
}- The
ifcheck looks for thenameproperty on details elements. Browsers that support the attribute have it, so the script does nothing there and the browser handles the group. document.querySelectorAll(".faq details")collects the details elements inside the.faqcontainer, so other details elements on the page stay independent.- Each one gets a listener for the
toggleevent, which the browser fires after an element opens or closes. WhentargetDetailhas just opened, the script removes theopenattribute from all the others, which closes them. - Elements added to the page later, for example with Ajax, aren’t in that list. Run the script again after they load, or rely on the
nameattribute, which doesn’t have that limit.
To test the script in Chrome, the test page removed Chrome’s support for the property before the page loaded and used details elements without a name. The script then gave the same results as the list above: one item open at a time for clicks, Enter, Space, script and anchor links.
Why listen for toggle and not click?
An earlier version of this script listened for click. That works for mouse clicks, and for Enter or Space on a focused summary, which fire a click too. But when a script set details.open = true, or a link to an anchor inside a closed item opened it, no click happened: in the test, two items ended up open. The toggle event fires however an element opens, so the fallback covers every case the name attribute covers.
Frequently asked questions
Does it work with the keyboard?
Yes. Pressing Enter or Space on a focused <summary> opens or closes its details element. With the name attribute the browser closes the others, and the fallback script reacts to the toggle event that follows.
Can one item be open when the page loads?
Yes. Add the open attribute to that <details> element, and to only one per group. If more than one has it, the browser keeps only the first open.
Related articles
- showing and hiding a div with a jQuery button: for content that isn’t in a details element
- running JavaScript again after an Ajax load: when parts of the page arrive later
