JoshWComeau

Animating “height: auto” in CSS

From
Josh W. Comeau
Reply-To
support@joshwcomeau.com
Sent
March 24, 2025

This issue of my newsletter was sent to newsletter subscribers.
Sign up to receive future issues!

Hey folks!

let’s suppose we’re building a collapsible accordion component, something like this:

Screen recording showing a UI with 3 collapsed items. The user clicks the top one and it expands to reveal some text inside, animating smoothly from not existing to becoming fully open. When another option is clicked, the top option collapses and the new option expands, both transitions happening smoothly

If you’ve ever tried to build something like this, you’ve likely been frustrated to realize that animating the height property doesn’t really work. We can transition between discrete values (eg. 0px to 300px), but not from 0px to auto.

The solution I’ve used in the past is to calculate the element’s internal height with .getBoundingClientRect(), but this approach is surprisingly tricky to get right; you’ll inevitably run into weird edge-cases and bugs as a result. 😬

Well, I have some good news! As CSS continues its “everything you’ve ever wanted” tour into 2025, we now have a solution to this age-old problem. 🎉

Here’s what it looks like:

screenshot of code showing a new CSS declaration, “interpolate-size: allow-keywords”, placed on the root html element

This curious new property “opts in” to the behavior we’ve always wanted. With this in place, we can now animate between 0px and auto using standard CSS transitions:

screenshot of code showing an element that has its height set either to “auto” or “0px” depending on a data attribute. It also has “transition: height 300ms” and “overflow: clip” set.

How cool is that?!

Now, unfortunately, this CSS property isn’t widely available yet. It’s only supported for about 2/3rds of users. But I’d argue that we can still start using this property today; folks on unsupported browsers won’t see the nice animation, but it’ll still work just fine. This is a perfect candidate, in my opinion, for progressive enhancement, as I wrote about in my recent post, “A Framework for Evaluating Browser Support”(opens in new tab).

I’ve added this declaration to my custom CSS reset(opens in new tab), so that this lovely new behaviour is the default for all new projects. 😄

My Custom CSS Reset

For the past few months, I’ve been hard at work on Whimsical Animations, my upcoming course. I’m beyond excited to share it with you. It’ll cover all of the cool things you can do with this interpolate-size superpower. And it’s so much more than a collection of cool tricks, it’s a comprehensive guide for designing and building your own top-tier animations and interactions.

If you’d like to follow the course’s development, you can join the waitlist! It’s a separate newsletter from the primary one you’re currently subscribed to, and I plan on sending free bonus content over the coming months. Folks on the waitlist will also be the first to know when registration opens. 💖

If you’re interested, you can sign up here:

This landing page includes a bunch of little easter eggs, and the idea is that the course will show you how to build stuff like this. We’ll cover a bunch of my most popular “special effects” in the course. 😄

That’s all I have for you today! Hope you’re doing well.

-Josh
PS. A question for you: what do you think about newsletter issues like this one, where I share a cool lil’ trick rather than a full new blog post? I often have smaller things like this to share, but I’m not sure if it warrants a whole newsletter issue or not.
You can let me know by replying to this email! Replies come straight to my personal inbox, and I read them all. ❤️

This issue of my newsletter was sent to newsletter subscribers.
Sign up to receive future issues!