Gustavo Alexandrino
Posted on January 9, 2023
Yes, this includes animating the closing of the element too!
Introduction
Animating the <details>
HTML element using only pure CSS can be a challenging task, as many articles, posts, and tutorials either rely on JavaScript or offer incomplete solutions that are unable to animate the closing of the element or produce a smooth animation.
However, with a bit of creativity, it is possible to create a fully-animated <details>
element using pure CSS.
This solution reproduces the example from Chris Coyier's CSS Tricks post, but achieves the same smooth animation without using any JavaScript – only CSS – for both opening and closing the element.
The CSS Solution
The key is to start the page with the details
element in its open state (<details open>
), then change its max-height
value by toggling a checkbox, and use a transition effect to animate that change.
details {
max-height: 4rem; /* Set a max-height value just enough to show the summary */
overflow: hidden; /* Hide the rest of the content */
transition: max-height 400ms ease-out; /* Animate the change */
}
To control the change of the element's max-height
value, you will need a checkbox and associate it with the <details>
element. You can choose from two approaches to do this, and both work great:
- Using the
+
adjacent sibling combinator - Using the
:has()
pseudo-class
input:checked + details,
details:has(input:checked) {
max-height: 576px; /* Set a max-height value enough to show all the content */
}
In the CSS, the selector input:checked + details
selects a <details>
element that immediately follows a checked input element. On the other hand, the selector details:has(input:checked)
selects a <details>
element that has a checked input element as its descendant.
The HTML
The difference between the two approaches in HTML is that the checkbox input must come immediately before the <details>
element in the first approach, and the checkbox must be a descendant of the <details>
element in the second approach.
Inside the <summary>
tag of the <details>
element , place a <label>
that toggles the checkbox:
<!-- approach #1 (checkbox comes immediately before the details element) -->
<input type="checkbox" name="approach-one" id="approach-one" />
<details open>
<summary>
<label for="approach-one">This one uses the adjacent sibling combinator (+) approach</label>
</summary>
<div class="rest-of-the-content">...</div>
</details>
<!-- approach #2 (checkbox is a descendant of the details element -->
<details open>
<summary>
<input type="checkbox" name="approach-two" id="approach-two" />
<label for="approach-two">This one uses :has() pseudo-class approach</label>
</summary>
<div class="rest-of-the-content">...</div>
</details>
A note about Firefox browser
One caveat to consider when using the :has()
approach is that in Firefox the user must explicitly enable this feature (see caniuse.com and MDN Web Docs).
Final result
Posted on January 9, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.