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>
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.
Share Improve this question edited Oct 12, 2017 at 18:11 Patrick asked Oct 10, 2017 at 14:04 PatrickPatrick 3,7595 gold badges35 silver badges59 bronze badges 8- Couldn't reproduce. In Safari 11.0 (macOS) it works as expected. – Styx Commented Oct 12, 2017 at 17:35
- @Styx I just tested in Safari 11.0 and the bug still happens. The "Hello" jumps to the bottom instead of being paused. – Patrick Commented Oct 12, 2017 at 17:53
- Try this jsfiddle, please: jsfiddle.net/iStyx/2uqf1p9y – Styx Commented Oct 12, 2017 at 17:59
- The timeout must be set to 1000 to reproduce the bug. – Patrick Commented Oct 12, 2017 at 18:02
- 1 I've played a lot with this thing, but it seems there is no workaround about this :( – Styx Commented Oct 13, 2017 at 2:37
2 Answers
Reset to default 12 +50The 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>