How can I transition height: 0; to height: auto; using CSS?
Pure CSS can’t directly animate a transition from height: 0;
to height: auto;
because the browser doesn’t know the numeric end value of “auto.” You need a numeric target for the transition. Below are some common workarounds:
1. Use max-height
Instead of height
A typical trick is to set a max-height
on the collapsed state and transition to a larger numeric max-height
on the expanded state. Choose a value large enough to accommodate the content’s maximum possible height:
.panel { overflow: hidden; max-height: 0; transition: max-height 0.4s ease; } .panel.open { /* Instead of 'auto', pick a sufficiently large number */ max-height: 500px; }
- How it works:
- When
.panel
does not have.open
,max-height
is0
, effectively hiding content. - Once
.open
is added,max-height
is set to500px
, and the height animates from0
to500px
. - Adjust
500px
to the maximum content height you expect.
- When
Caveat: If the content can vary in height more than your set max, you have to pick a safe upper bound or switch to a more dynamic approach (JS-based measurement).
2. Toggle a Known Fixed Height
If you know the final height in pixels (e.g., a fixed-size element):
.box { height: 0; overflow: hidden; transition: height 0.4s ease; } .box.open { height: 200px; /* A fixed numeric value */ }
- How it works:
- The browser can calculate the transition from
0px
to200px
because both are numeric. - No JavaScript needed, but this only works when the expanded height is fixed or predictable.
- The browser can calculate the transition from
3. Use transform: scaleY()
for an Accordion-like Effect
Another technique is to animate transform: scaleY(0)
to transform: scaleY(1)
, then hide overflow:
.accordion { transform-origin: top; transform: scaleY(0); transition: transform 0.4s ease; overflow: hidden; } .accordion.open { transform: scaleY(1); }
- How it works:
- “Collapsing” is done by scaling along the Y axis from 1 (full size) down to 0 (collapsed).
- If the container has
overflow: hidden;
, the content effectively disappears.
- Caveat:
- The scaling can distort nested elements (especially with complex or large contents). Sometimes you’ll see text “shrink” during the transition.
4. Use JavaScript to Dynamically Set the Final Height
If you need a fully dynamic solution—i.e., content height can vary—JavaScript is the most robust approach:
- Calculate the element’s
scrollHeight
(the full height of its content). - Set the element’s
height
from0
(or its current height) to that measured value.
const panel = document.querySelector('.panel'); const content = document.querySelector('.panel-content'); function openPanel() { // measure content height const finalHeight = content.scrollHeight; panel.style.height = finalHeight + 'px'; } function closePanel() { panel.style.height = '0px'; } // Add a transition in CSS // .panel { // overflow: hidden; // height: 0; // transition: height 0.4s ease; // }
- How it works:
- The browser can animate from
0px
to (e.g.)200px
, because both are numeric. - After the transition finishes, you can set
height: auto;
if you want the container to resize naturally.
- The browser can animate from
Pro Tip: To switch from a numeric height back to auto
without jarring transitions, you can:
- Listen for the
transitionend
event in JS. - Once the transition finishes, set
height: auto;
.
Summary
- Direct
height: auto;
transitions aren’t possible in pure CSS because “auto” is not a fixed numeric value. - Use
max-height
trick, fixed height, transform scaleY, or JS to achieve a similar effect. - For fully dynamic height expansions (like accordions with variable content), a JavaScript-based approach is the most reliable.
These techniques are common in collapsible/accordion UI patterns, ensuring a smooth, animated expansion/collapse.