HTML Beginner

Accordion disclosure without JavaScript

Accordions used to need JavaScript to toggle visibility, update aria-expanded, and manage keyboard events. The details and summary elements handle all of that natively.

Modern
4 lines
1<!-- No JS, no aria wiring -->
2<details>
3  <summary>What is CSS?</summary>
4  <p>CSS styles the web.</p>
5</details>
Old JS required
1<!-- HTML: custom markup -->
2<button aria-expanded="false" aria-controls="panel">What is CSS?</button>
3<div id="panel" hidden>...</div>
4// JS: toggle hidden + update aria-expanded on click
5btn.addEventListener('click', () => {
6  panel.toggleAttribute('hidden');
7  btn.setAttribute('aria-expanded', !panel.hidden);
8});
Widely available Since 2020 96% global usage

This feature is well established and works across many devices and browser versions. It has been available across browsers since 2020.

12+
49+
6+
79+
click to expand β€” no JavaScript
What is CSS nesting?
Write selectors inside selectors, just like Sass. No preprocessor needed. Supported in all major browsers since 2024.
What is the :has() selector?
A parent selector. Style an element based on what it contains. The most powerful selector addition in years.
What is container queries?
Style an element based on its container's size, not the viewport. Makes truly reusable components possible.
What is anchor positioning?
Position an element relative to another element anywhere in the DOM. No JavaScript getBoundingClientRect calculations needed.
<details> + <summary> β€” open/close managed by the browser
Kinsta

Your first month is free

Managed WordPress hosting for faster sites.

Learn more
⚑

No JavaScript

Click to expand, click to collapse. Keyboard accessible. The browser manages open state with zero JS.

✦

Accessible by default

The summary element is a button in the accessibility tree. No manual aria-expanded wiring needed.

∞

Styleable with CSS

Target the open attribute to style the expanded state. Use ::details-content for the panel and ::marker or list-style to customize the triangle.

Lines Saved
8 β†’ 4
No JS or aria wiring
Old Approach
JS click handler
Toggle hidden + aria-expanded
Modern Approach
<details>
Native expand/collapse

How it works

The <details> element is a disclosure widget. Wrap content in it and add a <summary> as the first child β€” the summary becomes the visible toggle. Everything else inside details is hidden until the user opens it.

The browser adds the open attribute when expanded. You can hook into it with CSS: details[open] summary { ... }. The disclosure triangle comes from ::marker on the summary β€” replace it with list-style: none and your own indicator.

For exclusive accordions where only one item is open at a time, give all details elements the same name attribute. The browser enforces mutual exclusivity automatically β€” no JavaScript needed for that either.

New CSS drops.

Join 600+ readers who've survived clearfix hacks.

ESC