cssanimationcss-transitionstransitionslide

No CSS transition for 'height: fit-content'


I use transition: height 500ms to add an animation to an element that slides open via button from height: 0 to height: 100px and vice versa.

Since the element's content is added dynamically and I don't know its size I would like to switch to height: fit-content instead. This way the element would have always the right size to show its content.

Sadly this disables the animation.

How can I get the animation together with a div element which size fits its content?

Following snippet shows the behavior:

document.querySelector('button')
  .addEventListener(
    'click',
    () => document.querySelectorAll('div')
      .forEach(div => div.classList.toggle('closed')));
div {
  background-color: lightblue;
  border: 1px solid black;
  overflow: hidden;
  transition: height 500ms;
}

div.closed {
  height: 0 !important;
}

div.div1 {
  height: 100px;
}

div.div2 {
  height: fit-content;
}
<button type="button">toggle</button>

<h1>'height: 100px' => 'height: 0'</h1>
<div class="div1">
some text<br />
even more text<br />
so much text
</div>

<br>

<h1>'height: fit-content' => 'height: 0'</h1>
<div class="div2">
some text<br />
even more text<br />
so much text
</div>


Solution

  • As Mishel stated another solution is to use max-height. Here is a working example of that solution.

    The key is to approximate your max-height when it is fully expanded, then the transitions will be smooth.

    Hope this helps.

    https://www.w3schools.com/css/css3_transitions.asp

    document.querySelector('button')
      .addEventListener(
        'click',
        () => document.querySelectorAll('div')
          .forEach(div => div.classList.toggle('closed')));
    div {
      background-color: lightblue;
      border: 1px solid black;
      overflow-y: hidden;
    	max-height: 75px; /* approximate max height */
    	transition-property: all;
    	transition-duration: .5s;
    	transition-timing-function: cubic-bezier(1, 1, 1, 1);
    }
    div.closed {
       max-height: 0;
    }
    <button type="button">toggle</button>
    
    <h1>'height: 100px' => 'height: 0'</h1>
    <div class="div1">
    some text<br />
    even more text<br />
    so much text
    </div>
    
    <br>
    
    <h1>'height: fit-content' => 'height: 0'</h1>
    <div class="div2">
    some text<br />
    even more text<br />
    so much text
    </div>