在Safari中,过渡期间的不透明度更改会闪烁

在Safari中,过渡期间的不透明度更改会闪烁,safari,webkit,css-transitions,flicker,translate3d,Safari,Webkit,Css Transitions,Flicker,Translate3d,我有一个合成div(它有translate3d),带有不透明度转换: #bad { background-color: red; -webkit-transition: opacity .5s linear; -webkit-transform: translate3d(0, 0, 0); } 如果在转换过程中更改其不透明度,它将在Safari中闪烁。 闪烁大约每三秒发生一次,类似于白色闪光 在Chrome中没有这样的问题 这个问题似乎并不局限于不透明度的改变——we

我有一个合成div(它有
translate3d
),带有
不透明度
转换:

#bad {
    background-color: red;
    -webkit-transition: opacity .5s linear;
    -webkit-transform: translate3d(0, 0, 0);
}
如果在转换过程中更改其
不透明度
,它将在Safari中闪烁。
闪烁大约每三秒发生一次,类似于白色闪光

在Chrome中没有这样的问题

这个问题似乎并不局限于不透明度的改变
——webkit transform
在转换过程中也会产生类似的效果:元素偶尔会以转换的最终状态之一呈现一次。

如果我删除
-webkit transform
,问题就会消失,但不幸的是,现在这不是一个选项。

我可以用其他方法在Safari中修复此问题吗?

这似乎是CoreAnimation中的一个bug。
凯文·多尔蒂和他提供的

我不确定,但我相信这是由一个核心动画错误引起的rdar://problem/12081774a.k.a.非动画内容的闪现

[……]

我相信Safari转换闪烁与我提交的bug直接相关。解决方法是使用
kCAFillModeBackwards
kCAFillModeBoth
的核心动画
fillMode
。动画计时似乎有问题,在同一事务中,属性值更改和在该属性上启动的动画实际上不会同时开始。向后填充通过扩展在实际开始时间之前应用的延迟开始动画的效果来解决此问题

凯文也报告了这一点,并试图解决它,但从我的理解,他没有继续这一点,补丁不被接受


当然,这不是一个真正的答案(不能解决问题),但至少它解释了问题。

问题是更改属性值和添加动画需要同时发生

< >在C++中重写核心动画时引入了OSX 10.5中不存在的竞争条件。当我的加性动画实验产生同样的闪烁时,我学会了这一点。我发现解决方法是核心动画的kCAFillModeBackwards。我还发现,同样的解决方法对于CSS转换也很有效,方法是修改我自己的WebKit分支,重点放在修改部分。但是猜测对WebKit开发人员没有帮助,我不想再打扰他们了。我确实认为问题在于核心动画,而不是WebKit。我猜他们应该在任何给定的CATTransaction中使用从对CACurrentMediaTime的单个调用中派生的相同CFTimeInterval

与过渡不同,CSS动画允许填充模式。复制转换行为可能很困难,但这是一种选择。特别是,挑战在于将中断的动画替换为从上一个动画停止的地方开始的新动画。换句话说,从0到1或1到0的不透明度设置动画很容易,但是如果用户希望在当前动画进度为0.577564时开始,会发生什么情况?这可能需要手动修改@keyframes样式规则,这不是一项简单的任务

然后是适当的动画填充模式的问题。通常,您不希望使用正向填充动画执行布局,而是使用CSS属性本身。但在这种情况下,它可能足够简单,不设置基础值,而只使用一个向前填充的CSS动画,该动画会被替换,但在完成后不会被删除。另一种方法是通过element.style设置基础值,同时添加向后填充的CSS动画

当然,如果WebKit不使用核心动画,闪烁也不会发生。到目前为止,在您的情况下,防止闪烁的最简单方法是不启用硬件加速

而不是:

-webkit-transform: translate3d(100px, 100px, 0);
尝试:


在我的案例中,我发现了3个解决相同问题的措施:

我需要在ready事件中淡入一个图像,尝试使用jQuery动画,但在OSX Safari上图像闪烁

通过以下行动解决:

1) 分析CSS并删除应用于图像的所有转换规则,它们似乎与动画命令冲突

我有这个规则

img {
/*DON'T COPY !!!*/
-webkit-transition:all 0.2s ease-in-out;
-moz-transition:all 0.2s ease-in-out;
-ms-transition:all 0.2s ease-in-out;
-o-transition:all 0.2s ease-in-out;
transition:all 0.2s ease-in-out;
/*DON'T COPY !!!*/
}
我把它删掉了

2) 将此CSS规则添加到需要淡入的元素:

display: none;/*initial state modified by the fadeIn function*/
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;
-webkit-font-smoothing: antialiased;
-webkit-transform-style: preserve-3d;
-webkit-transform: translateZ(0); 
3) 使用jQuery函数“fadeIn”,不要使用“.animate({opacity:1}ecc..”命令


这些操作解决了OSX Safari上的闪烁问题。

以下CSS修复了Safari上的转换闪烁

* {
-webkit-backface-visibility: hidden;
}

似乎相关:我花了两天时间在这上面,刚刚意识到了同样的事情(使用香草
翻译
)!感谢您的精彩写作。仅供参考,现在是2021年,这个答案解决了Safari在进行CSS不透明度转换时出现的一个问题(不是通过javascript)。在我的例子中,不透明度转换将导致父元素在转换开始时向上移动1像素,然后在转换结束时向下移动到其原始位置。
-webkit transform:translateZ(0);
解决了此问题。我很高兴它仍然有用!
* {
-webkit-backface-visibility: hidden;
}