I have a CSS animation with a delay and I pause it during the delay. It works as expected on Firefox and Chrome, the "Hello" does not move. However on Safari, the animation jumps to the last frame. Why and how to fix please?
function test() {
var timeout = 1000;
setTimeout(function() {
document.getElementById('animation').style.animationPlayState = 'paused';
}, timeout);
}
document.addEventListener("DOMContentLoaded", test);
#animation {
animation: test 2s linear 2s;
}
@keyframes test {
to {
transform: translateY(100px);
}
}
<div id="animation">
Hello (this text should not move)
</div>
If I remove the 2s delay, set the duration to 4s, and add a keyframe with transform:none, I can make this simple example work. However my real case has multiple animations that are synchronized with delays.
Safari supports two types of CSS animation: transition animations and keyframe animations.
Animation Duration Not Set By default, a CSS animation cycle is zero seconds long. To override this, add an animation-duration rule to your targeted element with a seconds value, in the same block as animation-name. Below, try removing the comments around animation-duration to fix the animation.
CSS Animation element is supported by all Microsoft Edge browser.
The Safari behaviour is only buggy when timeout is set to a value smaller than the animation delay. So, a workaround is to set the initial state to paused
via animation-play-state
and then control it via JS, as shown below:
function test() {
let el = document.getElementById("animation");
let timeout = 1000;
// Get the delay. No luck with el.style.animationDelay
let delay =
window
.getComputedStyle(el)
.getPropertyValue("animation-delay")
.slice(0, -1) * 1000;
// Only resume and later pause when timeout is greater than animation delay
if (timeout > delay) {
el.style.animationPlayState = "running";
setTimeout(function() {
el.style.animationPlayState = "paused";
}, timeout);
}
}
document.addEventListener("DOMContentLoaded", test);
#animation {
animation: test 2s linear 3s;
animation-play-state: paused; /* Pause it right after you set it */
}
@keyframes test {
to {
transform: translateY(100px);
}
}
<div id="animation">
Hello (this text should not move)
</div>
Try different timeout values to see it working. Can't say why this is happening though. Looks like a bug to me. Tested on OS X El Capitan 10.11.6 / Safari 11.0 (11604.1.38.1.7).
Codepen demo
This is not an answer to the problem. However, if you remove the animation delay, pausing and restarting the animation works as it should. It seems then the animation delay is what is causing the problem. Perhaps rather than relying on css to handle the delay, programmatically control animation delay with javascript.
See below pausing and running the animation
function test() {
var timeout = 1000;
setTimeout(function() {
document.getElementById('animation').style.animationPlayState ='paused';
document.getElementById('animation').style.webkitAnimationPlayState ='paused';
}, timeout);
setTimeout(function() {
document.getElementById('animation').style.animationPlayState='running';
document.getElementById('animation').style.webkitAnimationPlayState ='running';
}, timeout * 2);
}
document.addEventListener("DOMContentLoaded", test);
#animation {
-webkit-animation: test 2s linear;
animation: test 2s linear;
}
@-webkit-keyframes test {
to {
-webkit-transform: translateY(100px);
transform: translateY(100px);
}
}
@keyframes test {
to {
-webkit-transform: translateY(100px);
transform: translateY(100px);
}
}
<div id="animation">
Hello (this text should not move)
</div>
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