The combination of animation and transition does not work properly

I am trying to add some basic CSS3 animation. The goal is to switch the class to the button click event and animate the div based on the added class. The code works fine for the first iteration of switching in Firefox, but for other browsers such as Chrome, and for the next iteration in Firefox, the conversion turns into a blink of an eye. Please help me figure out what is going wrong.

Excerpt:

$('button').click(function() { $('div').toggleClass('clicked'); }); 
 div { background-color: #ccc; height: 100px; width: 100px; transition-property: top, left; transition-duration: 1s; transition-timing-function: linear; position: relative; top: 0; left: 0; } .clicked { animation-name: clicked; animation-duration: 1s; animation-timing-function: linear; animation-fill-mode: forwards; } @keyframes clicked { 0% { top: 0; left: 0; } 100% { top: 100px; left: 100px; } } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button type="button">Click Me!</button> <div></div> 

I also prepared a violin here .

+6
source share
2 answers

This is a kind of known behavior with Chrome. Firefox seems to be able to handle animation removal smoothly with transition, but Chrome does not. I have seen this behavior before and in this thread .

Why doesn't removing animations work with transition in Chrome?

So far I can’t give 100% proof of why this is happening, we can somewhat decipher it based on this HTML5Rocks article on accelerated rendering in Chrome and this is about accelerated GPU layout in Chrome .

It seems that the element gets its own rendering level, since it has an explicit position property on it. When a layer (or part of it) becomes invalid due to animation, Chrome only redraws that layer, which is affected by the change. When you open the Chrome developer’s console, turn on the option “Show painting objects”, you will see that when the animation happens, Chrome only draws the actual element, which becomes animated.

However, at the beginning and at the end of the animation, the entire page is redrawn, which immediately returns the element to its original position and thereby cancels the transition behavior.

 $('button').click(function(){ $('div').toggleClass('clicked'); }); 
 div{ background-color: #ccc; height: 100px; width: 100px; transition-property: top, left; transition-duration: 1s; transition-timing-function: linear; position: relative; top: 0; left: 0; } .clicked{ animation-name: clicked; animation-duration: 1s; animation-timing-function: linear; animation-fill-mode: forwards; } @keyframes clicked{ 0% {top: 0; left: 0;} 100% {top: 100px; left: 100px;} } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button type="button">Click Me!</button> <div></div> 

What's the solution?

Since your movement is actually a linear movement from one position to another, you can achieve it without the need for animation. All we need to do is use the translate transform and shift the element to the desired no value. pixels when you enable the class. Since there is a transition assigned to an element through another selector, the offset will occur in a linear manner. While the class is switching, the element returns to its original position again in a linear fashion due to the transition to the element.

 $('button').click(function() { $('div').toggleClass('clicked'); }); 
 div { background-color: #ccc; height: 100px; width: 100px; transition-property: transform; transition-duration: 1s; transition-timing-function: linear; position: relative; top: 0; left: 0; } .clicked { transform: translate(100px, 100px); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> <button type="button">Click Me!</button> <div></div> 
+5
source

This is the expected behavior. You need to use two separate animations or stick to just the transition.

A transition is an animation, only one, that is executed between two different states, that is, the state of the beginning and the final state. Like a menu box, the start state can be open and the end state can be closed, or vice versa.

If you want to accomplish something that is not specifically related to the initial state and final state, or you need more precise grain management of key transition frames, then you should use animation.

This is a way to animate an element with a transition:

 $('button').click(function() { $('div').toggleClass('clicked'); }); 
 div { background-color: #ccc; height: 100px; width: 100px; transition-property: top, left; transition-duration: 1s; transition-timing-function: linear; position: relative; top: 0; left: 0; } .clicked { top: 100px; left: 100px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button type="button">Click Me!</button> <div></div> 
+4
source

All Articles