eight: auto. We often ended up writing messy JS scripts to calculate scrollHeight` on the fly. To understand how far we've come with modern motion, you might want to revisit our article on Advanced CSS Animations: Keyframes vs Transitions.
The modern way in 2026
In 2026, styling these elements is a breeze. We have ::marker to handle the icons, flex or grid to align the summary content, andāthe absolute game-changerāthe interpolate-size property which finally allows us to animate to auto height.
The modern approach involves treating the <summary> as a flex container. This lets us put icons on the left, text in the middle, and status indicators on the right without breaking a sweat. We also use the [open] attribute selector to change styles when the content is revealed. If you're building complex layouts, combine this with Style Queries: Container Style Queries to make your accordions react to their parent container's dimensions or styles.
Ready-to-use code snippet
Here is a clean, modern implementation. It features a custom animated plus/minus icon and a smooth reveal effect using interpolate-size (supported in the latest browsers).
<style>
:root {
interpolate-size: allow-keywords;
}
.custom-accordion {
max-width: 500px;
border: 1px solid #e0e0e0;
border-radius: 8px;
overflow: hidden;
font-family: sans-serif;
}
details {
border-bottom: 1px solid #e0e0e0;
transition: background 0.3s ease;
}
details:last-child {
border-bottom: none;
}
details[open] {
background: #f9f9f9;
}
summary {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem;
cursor: pointer;
list-style: none; /* Removes default arrow */
font-weight: 600;
}
/* Standard way to hide the marker */
summary::-webkit-details-marker {
display: none;
}
summary::after {
content: '+';
font-size: 1.5rem;
transition: transform 0.3s ease;
}
details[open] summary::after {
transform: rotate(45deg);
}
.content {
padding: 0 1rem 1rem;
height: 0;
overflow: hidden;
transition: height 0.4s ease-out, opacity 0.3s ease;
opacity: 0;
}
details[open] .content {
height: auto;
opacity: 1;
}
</style>
<div class="custom-accordion">
<details>
<summary>What is the benefit of this approach?</summary>
<div class="content">
<p>It is lightweight, accessible by default, and requires zero JavaScript for the core functionality.</p>
</div>
</details>
<details>
<summary>Is it SEO friendly?</summary>
<div class="content">
<p>Absolutely! Search engines see the content immediately because it is present in the DOM from the start.</p>
</div>
</details>
</div>
Common beginner mistake
The biggest mistake I see? People forget that <summary> has a default display: list-item in many browsers. If you try to apply display: flex to it without realizing this, you might run into weird layout bugs or find that the default "triangle" arrow refuses to disappear in certain browsers like Safari. Always explicitly hide the ::marker and the non-standard ::-webkit-details-marker if you are providing your own icon.
Also, avoid putting interactive elements like buttons or links directly inside the <summary> tag. The summary itself acts as a button; putting a button inside a button is a classic accessibility fail that will confuse screen reader users and potentially break the toggle behavior.
š„ We publish more advanced CSS tricks, ready-to-use snippets, and tutorials in our Telegram channel. Subscribe so you don't miss out!