Bonafide CSS trick alert! Nelson Menezes figured out a new way (that only works in Firefox for now) that is awfully clever.
Perhaps you know that CSS cannot animate to auto
dimensions, which is super unfortunate. Animating from zero to “whatever is necessary” would be very helpful very often. We’ve documented the available techniques. They boil down to:
- Animate the
max-height
to some more than you need value, which makes timing easing imprecise and janky. - Use JavaScript to measure the final size and animate to that, which means… using JavaScript.
Nelson’s technique is neither of those, nor some transform
-based way with visual awkwardness. This technique uses CSS Grid at its core…
.expander {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 1s;
}
.expander.expanded {
grid-template-rows: 1fr;
}
Unbelievably, in Firefox, that transitions content inside that area between 0 and the natural height of the content. There is only a little more to it, like hiding overflow and visibility to make it look right while maintaining accessibility:
That’s wonderful. Let’s get some stars on this issue and maybe Chrome will pick it up. But of course, even better would be if auto
height transitions just started working. I can’t imagine that’s totally outside the realm of possibility.
Finally!!
I stumbled upon something similar to this whilst trying to animate a horizontal drawer. Sadly I don’t think it works for
grid-template-columns
. Do you think there is any deeper reason as to why or just waiting on vendor implementations?Awesome, great trick.
I created another version, where a configurable number of lines are previewable by default, check it out:
https://codepen.io/vajkri/full/oNeaBxG
Dear Chris,
Thank you so much for your informative website!
Here is my approach to auto height transition:
https://stackoverflow.com/a/69871346/478018
I wonder what you think.
Very interesting!
Here’s a fork of the demo in this post but with your technique:
There are some interesting caveats. Like the flex items themselves will transition, but if an element lives outside the flex container, that will jump to the final position.
And it’s super interesting how the parent of the flex container needs to be grid (or flex) to work???
“if an element lives outside the flex container”
As you see in my demo, the rest of your page content should be in the flex container, i.e. the
body
element.