Skip to main content
Dublin Library

The Publishing Project

Exclusive Accordions

 

Accordions present an interesting way to display content using one or more [details](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details) elements. There is a specific type of accordion that, until recently, was impossible to do without scripting, the exclusive accordion. This post will explain what's an exclusive accordion and how to polyfill the API to handle older browsers. ## What are exclusive accordions and how they work To achieve this on the web you can now a `name` attribute to `details` elements. When this attribute is used, all `details` elements with the same name value form a semantic group and will behave as an exclusive accordion. When you open one of the `details` elements that share the same name, the previously opened one will automatically close. In the example below we have three items in the accordion with the first one being open by default when the page opens. When you click on the other items, it will open the item you click and close the one currently open. ```html

Latest Posts

Post 1

This is the content for the post.

Read More

Post 2

This is the content for the post.

Read More

Post-3

This is the content for the post.

Read More

``` This is what the exclusive accordion looks like with CSS applied to it. You can have multiple exclusive accordions, each group sharing a name. The elements of the exclusive accordion don't have to be next to each other for the accordion to work. ## Javascript Polyfill Maintaining backward compatibility is not complicated. We can polyfill the behavior of the exclusive accordion. The code relies on the `toggle` event of the `details` element to close all the details elements with the same name, except the one that was just opened. ```js document.querySelectorAll("details[name]").forEach(($details) => { $details.addEventListener("toggle", (e) => { const name = $details.getAttribute("name"); if (e.newState == "open") { document .querySelectorAll(`details[name=${name}][open]`) .forEach(($openDetails) => { if (!($openDetails === $details)) { $openDetails.removeAttribute("open"); } }); } }); }); ``` ## Links and Resources * [Exclusive Accordion (Explainer)](https://open-ui.org/components/accordion.explainer/) — Open UI * [Exclusive Accordion](https://developer.chrome.com/docs/css-ui/exclusive-accordion) — Chrome Developers

Edit on Github