Logo

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 is 0, effectively hiding content.
    • Once .open is added, max-height is set to 500px, and the height animates from 0 to 500px.
    • Adjust 500px to the maximum content height you expect.

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 to 200px because both are numeric.
    • No JavaScript needed, but this only works when the expanded height is fixed or predictable.

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:

  1. Calculate the element’s scrollHeight (the full height of its content).
  2. Set the element’s height from 0 (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.

Pro Tip: To switch from a numeric height back to auto without jarring transitions, you can:

  1. Listen for the transitionend event in JS.
  2. 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.

CONTRIBUTOR
TechGrind