If you want to collapse/expand elements with dynamic content (and thus unknown height), you can not transition between height: 0
and height: auto
.
Doing it properly, with modern CSS features
In the past, you might have resorted to bulky JavaScript solutions or CSS hacks like transitioning between max-height: 0
and max-height: 9999px
. All of them were awkward and/or have several edge cases.
With modern CSS, there is actually a way to do it properly:
Just use a display: grid
container which transitions its grid row height between 0fr
and 1fr
.
1fr
will make your container as tall as its content needs to be, but not taller.
Example
Your HTML needs to be structured like so:
<div class="foldable">
<div>
Your content goes here.
</div>
</div>
Note that your foldable element needs to contain exactly one child. This is because we want to transition that cell from 0fr to 1fr and back.
Put your content inside that child / grid cell. Your content may contain whatever you want, no restrictions apply. We just need it to be wrapped by the grid cell.
Then, style your foldable element like so:
.foldable {
display: grid;
align-items: start;
grid-template-rows: 1fr;
transition: grid-template-rows 1s;
}
.foldable,
.foldable > * {
overflow: hidden;
}
.foldable[aria-hidden="true"] {
grid-template-rows: 0fr;
}
In this example, we've chosen aria-hidden="true"
to specify if the element is collapsed, but you can do that however you like.
Note how we apply overflow: hidden
on both the grid container and its single cell. This is required for collapsing/expanding to look correct.
Also note that align-items: start
is required for the content to be locked to the foldable container's top during transition.
Interactive demo
I've also set up a codepen to demo this: https://codepen.io/foobear/pen/yLGONdo Show archive.org snapshot