Tested in Google Chrome 73 (Official Build) (64-bit).
Also tested in latest stable Mozilla, Opera and Safari.
Looks like it is a bug of Chrome only. Hope there is a workaround until the Chrome team fix the bug.
I have created Codepen to show the problem.
const div = document.querySelector('div');
const cssTransition = 2500;
const states = [
['INITIAL', 'translate(0)', cssTransition / 2],
['A', 'translate(0, 100px)', cssTransition + 500],
['B', 'translate(100px, 100px)', cssTransition / 2],
];
let cursor = 0;
const animate = () => {
cursor = (cursor + 1) % states.length;
const [name, value, delay] = states[cursor];
setTimeout(() => {
div.innerText = name;
div.style.transform = value;
animate();
}, delay);
};
animate();
div {
width: 100px;
height: 100px;
background: brown;
color: white;
font-size: 25px;
font-family: sans-serif;
text-align: center;
line-height: 100px;
margin: 50px auto;
transition: 2.5s ease;
}
<div>INITIAL</div>
Animate element via JavaScript to change its position on the screen using CSS3 transform property.
Conditions:
The problem is - transition is not smooth because new animation jumps from initial position of previous animation instead of smooth transition from current location.
When CSS transform property of an element is changed during transition (i.e. before current animation finished) the next animation starts from the initial state of previous animation.
As you can see, animation jumps to INITIAL state which is wrong (undesired). Position at step 6 should be near step 3.
CSS transform property change should reset internal animation timer to 0 (so, new animation will last as defined in transition property) but keep current transform state as initial state for the next animation.
As you can see, new animation starts exactly where it is expected - from step 3 and nicely move element to the new position.
Thanks for reading. Looking forward for your help.
So, what's the difference between CSS Transform and CSS Transition? The Transform property in CSS moves or modifies the appearance of an element, whereas the Transition property seamlessly and gently transitions the element from one state to another.
It works as follows: The overlay resting state is set to the right of the element using a margin (while the left is positioned to the left of the element). Upon hover, we set the margin to 0 without an animation. This allows the left animation to occur from the left side of the element.
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 transform CSS property lets you rotate, scale, skew, or translate an element. It modifies the coordinate space of the CSS visual formatting model.
I am unsure why it happens but a solution would be to manually set the transitioned property (here transform
) to its currently computed value, right before changing to the new desired one.
div.style.transform = getComputedStyle(div).transform;
// Cause a reflow to force the browser to apply the set transform
div.innerWidth;
div.style.transform = value;
Here is a fork of your pen including the fix.
getComputedStyle
is widely supported so you don't need to worry about a polyfill unless you want to support IE < 9
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