Read more

How to transition the height of elements with unknown/auto height

Arne Hartherz
August 29, 2023Software engineer at makandra GmbH

If you want to collapse/expand elements with dynamic content (and thus unknown height), you can not transition between height: 0 and height: auto.

Doing it properly, with modern CSS features

Illustration book lover

Growing Rails Applications in Practice

Check out our e-book. Learn to structure large Ruby on Rails codebases with the tools you already know and love.

  • Introduce design conventions for controllers and user-facing models
  • Create a system for growth
  • Build applications to last
Read more Show archive.org snapshot

In the past, you might have resorted to bulky JavaScript solutions or CSS hacks like transitioning between max-height: 0 and max-height: 9999px. All of them were awkward and/or have several edge cases.

With modern CSS, there is actually a way to do it properly:
Just use a display: grid container which transitions its grid row height between 0fr and 1fr.

1fr will make your container as tall as its content needs to be, but not taller.

Example

Your HTML needs to be structured like so:

<div class="foldable">
  <div>
    Your content goes here.
  </div>
</div>

Note that your foldable element needs to contain exactly one child. This is because we want to transition that cell from 0fr to 1fr and back.

Put your content inside that child / grid cell. Your content may contain whatever you want, no restrictions apply. We just need it to be wrapped by the grid cell.

Then, style your foldable element like so:

.foldable {
  display: grid;
  align-items: start;
  grid-template-rows: 1fr;
  transition: grid-template-rows 1s;
}
.foldable,
.foldable > * {
  overflow: hidden;
}
.foldable[aria-hidden="true"] {
  grid-template-rows: 0fr;
}

In this example, we've chosen aria-hidden="true" to specify if the element is collapsed, but you can do that however you like.

Note how we apply overflow: hidden on both the grid container and its single cell. This is required for collapsing/expanding to look correct.
Also note that align-items: start is required for the content to be locked to the foldable container's top during transition.

Interactive demo

I've also set up a codepen to demo this: https://codepen.io/foobear/pen/yLGONdo Show archive.org snapshot

Posted by Arne Hartherz to makandra dev (2023-08-29 16:07)