Safari 中的 CSS 动画错误

Posted

技术标签:

【中文标题】Safari 中的 CSS 动画错误【英文标题】:CSS animation bug in Safari 【发布时间】:2018-03-21 23:35:08 【问题描述】:

我有一个延迟的 CSS 动画,我在延迟期间暂停了它。 它在 Firefox 和 Chrome 上按预期工作,“你好”不动。 但是在 Safari 上,动画会跳到最后一帧。 请问为什么以及如何解决?

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>

如果我删除 2 秒延迟,将持续时间设置为 4 秒,并使用 transform:none 添加关键帧,我可以使这个简单的示例工作。然而,我的真实案例有多个与延迟同步的动画。

【问题讨论】:

无法重现。在 Safari 11.0 (macOS) 中,它按预期工作。 @Styx 我刚刚在 Safari 11.0 中进行了测试,但错误仍然存​​在。 “你好”会跳到底部而不是被暂停。 试试这个jsfiddle,请:jsfiddle.net/iStyx/2uqf1p9y 超时时间必须设置为 1000 才能重现错误。 我玩过这个东西很多,但似乎没有解决方法:( 【参考方案1】:

只有当超时设置为小于动画延迟的值时,Safari 的行为才会出现问题。所以,解决方法是通过animation-play-state设置初始状态为paused,然后通过JS控制,如下图:

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>

尝试不同的超时值以查看它是否正常工作。不能说为什么会这样。对我来说似乎是一个错误。在 OS X El Capitan 10.11.6 / Safari 11.0 (11604.1.38.1.7) 上测试。

Codepen demo

【讨论】:

谢谢。我也得出结论,这是一个错误,特别是因为我发现了其他错误。 Safari 的动画似乎令人难以置信。我想我必须用 javascript 重写所有内容。【参考方案2】:

这不是问题的答案。但是,如果您删除动画延迟,则暂停和重新启动动画会正常工作。看来动画延迟是导致问题的原因。也许与其依靠 css 来处理延迟,不如使用 javascript 以编程方式控制动画延迟。

见下文暂停和运行动画

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>

【讨论】:

谢谢。是的,我注意到了。我找到了另一种解决方法,我删除了延迟并添加了关键帧和不同的动画。 我还注意到您的代码在移动版 Safari 9.0 上无法正常工作。文本前后移动。 是的,在动画播放状态和 safari 方面肯定存在一些错误。

以上是关于Safari 中的 CSS 动画错误的主要内容,如果未能解决你的问题,请参考以下文章

动画播放状态在 Safari 上不起作用

调整带有动画“translate(%)”的元素大小时 Safari 错误的解决方法

运行不相关的动画时,Safari 会更改字体粗细

速记中的 CSS3 动画播放状态在 IE 和 Safari 中不起作用

简单的 CSS 动画在 Safari 中不流畅

Safari CSS Bug:动画旋转方向不正确?