How To Do CSS Transitions With Height: Auto
Creating a smooth expand/collapse animation seems easy. Surely you can set a transition on
height: auto, and it'll just work?
Sadly, the CSS gods aren't so kind.
Instead of the smooth open and close you wanted, your element flashes to its new height. No smooth animation.
As it turns out, animating on CSS
auto values doesn't work, and it's honestly a real shame. We need to use specific values, and that's not a luxury we always have.
Fortunately, there are several approaches we can take to animating auto dimensions in CSS.
Method 1: Use
Despite its rampant use, you should avoid CSS transitions on the
width properties (among some others).
These properties affect the page layout. To see how other elements on the page are being affected during your animation, the browser completely recalculates your page's layout.
For every. single. frame.
This is where the CSS
transform property comes in.
transform causes your element to be animated like an image, and skip the layout recalculations. If you can use this approach, you should.
Unfortunately, there are two deal-breakers in using
transform to collapse your content:
- The content warps when it collapses.
- It leaves a gap where the content was.
Method 2: Animate
A different approach to collapsing
height is to collapse
max-height in its place.
The upside of this approach is that it's straightforward. It also manages to avoid the weird warping effect of
There are some downsides, though:
- We're animating on
height, with all its layout-thrashing goodness
- You need a non-auto value for
transition-timingapplies to the
height. This makes it nearly impossible to get a specific visual effect from your transitions.
Method 3: Calculate
Once we determine the element's actual height, we can inject it as inline CSS so the browser has something to transition between.
In terms of effect, this is probably the one you were going for, but with tradeoffs.
- We're still animating on
- We've introduced a fair chunk of code to address a very narrow problem
Method 4: Nuke from orbit with FLIP + Inverse Scaling
Remember Method 1 and all the problems that using
Well, it turns out you can fix them.
Content warping can be fixed by applying counter-scaling on your content. The FLIP technique also lets us move surrounding content in a performant way.
This looks much better than our initial
transform attempt, and solves the problems we were having. However:
- This solution is big and complex. We've introduced a lot of code now, and it's still a very narrow problem.
- Several moving parts need to stay synchronised
- We need a custom easing function. I've used
linearfor simplicity, but anything else gets gnarly.
- Even more coupling than the