While working on this site, I wound up using the HTML <details> and <summary>
tags. They’re quite neat if you’re trying to go by with as little client-side JS
as possible, but the only downside is that they don’t support transitions out of
the box, or atleast it seems complicated.
A simple search brought up the humble MDN page:
which demonstrates adding a smooth fade-in/out animations on the details content
using the ::details-content pseudo selector (baseline 2025). This was very neat
and can be applied by simply following the guide they gave. It looked good and is
something I did end up using in the final version.
I wanted to implement a height-based transition as well. We know that animating
height is always a pain due to the inability to animate from height: 0 to
height: auto, however, this time around I stumbled upon this excellent article:
But the technique discussed there by setting display: grid and animating the
grid-template-rows didn’t seem to work here (possible skill issue). Finally, I found
this article:
This was a long-needed feature and this is how I used it to create the final effect:
<details>
<summary>Summary</summary>
<ul>
<li>First list item</li>
<li>Second list item</li>
<li>Third list item</li>
</ul>
</details>
/* required for animating height:auto */
:root {
interpolate-size: allow-keywords;
}
details::details-content {
height: 0;
opacity: 0;
overflow: hidden;
transition:
height 300ms,
opacity 300ms,
content-visibility 300ms allow-discrete;
}
details[open]::details-content {
height: auto;
opacity: 1;
content-visibility: visible;
}
…and that’s it! See it in action below:
See the Pen Better Accordion no JS by priyansh agrahari (@r3dacted42) on CodePen.
Thanks for reading! Feedbacks and suggestions welcome :)