When setting the height of an element to 0 in JavaScript and then immediately changing it to a specific value, the CSS transition for the element doesn't work.
However, by placing the code to increase the height inside a setTimeout()
, even with a delay of 0, the transition works, as you can see in the following snippet:
// Doesn't work:
document.getElementById("one").setAttribute("style", "height: 0px");
document.getElementById("one").setAttribute("style", "height: 200px");
// Works:
document.getElementById("two").setAttribute("style", "height: 0px");
setTimeout(function() {
document.getElementById("two").setAttribute("style", "height: 200px");
}, 0);
div {
display: inline-block;
width: 200px;
background-color: black;
transition: height 1s;
}
#two {
background-color: blue;
}
<div id="one">
</div>
<div id="two">
</div>
This behavior is consistent across all major browsers. The problem with this is, that sometimes, there seems to be some kind of lag, which makes the workaround not animate as well. So this doesn't seem to be a clean solution.
What causes the transition to cancel and how can I get around this cleanly?
To trigger an element's transition, toggle a class name on that element that triggers it. To pause an element's transition, use getComputedStyle and getPropertyValue at the point in the transition you want to pause it. Then set those CSS properties of that element equal to those values you just got.
The transition effect will start when the specified CSS property (width) changes value.
CSS allows animation of HTML elements without using JavaScript or Flash! In this chapter you will learn about the following properties: @keyframes.
It works like this: CSS values can only be transitioned to and from fixed unit values. But imagine we have an element whose height is set to auto , but whose max-height is set to a fixed value; say, 1000px . We can't transition height , but we can transition max-height , since it has an explicit value.
Most likely browsers optimize transitions and will merge changes which take less than 16ms (which would get you a refresh rate of about 60 frames per second)
So the solution is to simply wrap style changes nested RAF calls (tell the browser to animate when it's ready rather than after an arbitrary timeout)
window.requestAnimationFrame(function(){
document.getElementById("two").setAttribute("style", "height: 0px");
window.requestAnimationFrame(function(){
document.getElementById("two").setAttribute("style", "height: 200px");
});
});
reference: https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With