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>
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>