Animating auto height for accordion component
Accordion component is an element with a title and some content that can get hidden or displayed by clicking the title. There is a native HTML version of that done with a combination of <details>
and <summary>
elements but without built-in animation. At Hugo, we have Preact component called Panel
.
I know a couple of ways of getting Panel
to animate:
¶ 1. Animating max-height
You can’t animate between numeric and auto
values in CSS. So instead we animate between two numeric values of max-height
property. Starting value will be 0 and end value will be some arbitrary number, large enough so the content inside doesn’t get clipped.
.content {
overflow: hidden;
max-height: 0;
transition: max-height 0.3s ease;
}
#state:checked ~ .content {
max-height: 150px;
}
Here is a CSS-only demo, using good ’ol checkbox hack:
See the Pen Accordion animation by Teo Dragovic (@teodragovic) on CodePen.
¶ 2. Using React Animate Height
React Animate Height does exactly what it says. It’s a nice, little utility library that helps animate React components using CSS. I used it to avoid dealing with event handling myself.
<div className="c-panel__content">
<AnimateHeight height={ expanded ? 'auto' : 0 }>
{ children }
</AnimateHeight>
</div>
¶ 3. Using JavaScript
In an attempt to reduce our bundle size and number of dependencies, I dropped React Animate Height in favor of a simple, custom approach.
See the Pen Preact Panel by Teo Dragovic (@teodragovic) on CodePen.
We didn’t have any uses for animating height outside Panel
component and that itself was used only in a few places so this super lightweight approach worked for us.
¶ 4. Using CSS Grid
Great trick by Nelson Menezes (and reposted by CSS-Tricks) by using CSS Grid. This is my current prefferd approach.
.expander {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 1s;
overflow: hidden;
}
.expander.expanded {
grid-template-rows: 1fr;
}
See the Pen Preact Panel by Teo Dragovic (@teodragovic) on CodePen.