Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS transition doesn't animate when immediately changing size via JavaScript

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?

like image 280
Simon Mathewson Avatar asked Dec 31 '16 11:12

Simon Mathewson


People also ask

How do you trigger transitions in JavaScript?

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.

What triggers CSS transition?

The transition effect will start when the specified CSS property (width) changes value.

Does CSS animation use JavaScript?

CSS allows animation of HTML elements without using JavaScript or Flash! In this chapter you will learn about the following properties: @keyframes.

Does transition auto height work?

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.


1 Answers

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

like image 91
Tudor Ilisoi Avatar answered Sep 19 '22 17:09

Tudor Ilisoi