CSS Transform 导致 Safari 闪烁,但仅当浏览器宽度 >= 2000px 时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15751012/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 22:17:25  来源:igfitidea点击:

CSS Transform causes flicker in Safari, but only when the browser is >= 2000px wide

csssafaritransformcss-transitions

提问by Brandon Durham

You read that right. Tested on multiple machines in the office and the only difference between scenarios was browser size. A coworker narrowed it down to a 2000px sweet spot. Lo-and-behold when we each resize our browsers to be >= 2000px wide and mouse over an element with a transform animation various elements on the page — specifically any element with a CSS gradient background — will flicker. Inversely, if you resize the browser to be < 2000px wide and mouse over that same element no flickering occurs.

你没看错。在办公室的多台机器上进行了测试,场景之间的唯一区别是浏览器大小。一位同事将其缩小到 2000 像素的最佳位置。当我们每个人将浏览器的大小调整为 >= 2000px 宽并将鼠标悬停在具有变换动画的元素上时,页面上的各种元素(特别是具有 CSS 渐变背景的任何元素)都会闪烁。相反,如果您将浏览器的大小调整为 < 2000px 宽并将鼠标悬停在同一元素上,则不会发生闪烁。

Anyone else seen this bizarre behavior? Why is 2000px a magic number, and what exactly happens at 2000px?

其他人见过这种奇怪的行为吗?为什么 2000px 是一个神奇的数字,而 2000px 究竟会发生什么?

NOTE— I can't really share screenshots/video/links as this site isn't yet public, and code is relatively unnecessary as this seems to be more of a browser issue than anything.

注意——我不能真正分享屏幕截图/视频/链接,因为这个网站还没有公开,代码相对来说是不必要的,因为这似乎更像是一个浏览器问题。

NOTE 2— My question here is really around what exactly happens in Safari at 2000px, not necessarily how to fix the flicker with backface-visibilityor translateZor the like. Reason being that we use -webkit-font-smoothing: subpixel-antialiased;liberally throughout the site and using any of these tricks trumps that property for the entire page, turning on antialiasing / grayscale for all text.

注2-在这里我的问题是真正围绕什么,在Safari中究竟发生在2000像素,不一定如何与修复闪烁backface-visibilitytranslateZ等。原因是我们-webkit-font-smoothing: subpixel-antialiased;在整个网站上大量使用,并且使用这些技巧中的任何一个都胜过整个页面的属性,为所有文本打开抗锯齿/灰度。

EDIT —Okay, sorry for not having done this earlier. Here is a bit of code in a jsFiddle that should reproduce the issue: http://jsfiddle.net/brandondurham/ujPMK/embedded/result/

编辑 -好的,很抱歉没有早点这样做。这是 jsFiddle 中的一些代码,应该可以重现该问题:http: //jsfiddle.net/brandondurham/ujPMK/embedded/result/

Remember, Safari has to be set to at least 2000px wide for this to happen.

请记住,Safari 必须设置为至少 2000 像素宽才能发生这种情况。

回答by Spoeken

Frustrating huh?

令人沮丧吧?

See EDIT4 for the answer to why 2000px is a magic number.

有关为什么 2000px 是一个神奇数字的答案,请参阅 EDIT4。

There is a couple of things you can try.

您可以尝试几件事。

  • Add -webkit-transform-style: preserve-3d;to the elements that are flickering.

  • add -webkit-backface-visibility: hidden;to the elements that are
    flickering.

  • move the animating element outside of the parent the flickering
    elements are within.

  • 添加-webkit-transform-style: preserve-3d;到闪烁的元素。

  • 添加-webkit-backface-visibility: hidden;
    闪烁的元素。

  • 将动画元素移动到闪烁
    元素所在的父级之外。

EDIT— Wesley Hales, said here"I encountered glitchy behaviour when applying hardware acceleration to parts of the page that were already accelerated"

编辑— 韦斯利·黑尔斯 (Wesley Hales)在这里说 “在将硬件加速应用于已经加速的页面部分时,我遇到了故障行为”

Its hard to help you debug this without any code. But for starters I suggest you turn on debug mode in safari. Write 'defaults write com.apple.Safari IncludeInternalDebugMenu -bool true' in the terminal.

没有任何代码很难帮助您调试它。但是对于初学者,我建议您在 safari 中打开调试模式。在终端中写入“defaults write com.apple.Safari IncludeInternalDebugMenu -bool true”。

After this a Debug menu will show up. Choose Drawing/Compositing flags > Show Compositing borders.

在此之后,将显示调试菜单。选择“绘图/合成标志”>“显示合成边框”。

This will help you see whats being rendered and by that choose what to put in hardware acceleration and what to leave out.

这将帮助您查看正在渲染的内容,并由此选择将哪些内容放入硬件加速中以及将哪些内容排除在外。

EDIT2— This is worth checking out as well: fast-animation-with-ios-webkit

EDIT2— 这也值得一试:fast-animation-with-ios-webkit

Its regarding iOs, but I've experienced that - in some circumstances - solutions that work on iOs also works on osx.

它是关于 iOs 的,但我经历过——在某些情况下——适用于 iOs 的解决方案也适用于 osx。

EDIT3— If you are just asking what happens when its bigger than 2000px I can tell you for sure that on iPhones, WebKit creates textures that are no larger than 1024 by 1024, and if your element is larger than that, it has to create multiple textures.

EDIT3——如果你只是问当它大于 2000px 时会发生什么,我可以肯定地告诉你,在 iPhone 上,WebKit 创建的纹理不大于 1024 x 1024,如果你的元素大于这个,它必须创建多个纹理。

Documentation on texture limitations

关于纹理限制的文档

Now, when they do it on iPhone, it wouldn't surprise me if they do the same on OsX, but has a higher limit.

现在,当他们在 iPhone 上这样做时,如果他们在 OsX 上做同样的事情,我不会感到惊讶,但有更高的限制。

Don't know if this is your case tho. Impossible to tell without any code.

不知道你是不是这种情况。没有任何代码就无法判断。

EDIT4— "The implementation in TextureMapperTiledBackingStore is pretty simple, and is used only to work around the 2000x2000 texture size limitation in OpenGL."

EDIT4— “ TextureMapperTiledBackingStore 中的实现非常简单,仅用于解决 OpenGL 中 2000x2000 纹理大小的限制。”

So, if your element is bigger than 2000x2000 it has to create multiple textures.

因此,如果您的元素大于 2000x2000,则必须创建多个纹理。

http://trac.webkit.org/wiki/CoordinatedGraphicsSystem

http://trac.webkit.org/wiki/CoordinatedGraphicsSystem

回答by Rupam Datta

I found that applying the -webkit-backface-visibility: hidden;to the translating element and -webkit-transform: translate3d(0, 0, 0);to all its children, the flicker then disappears.

我发现将 应用于-webkit-backface-visibility: hidden;翻译元素及其-webkit-transform: translate3d(0, 0, 0);所有子元素,闪烁就会消失。

Please refer Prevent flicker on webkit-transition of webkit-transform.

请参阅webkit-transform 的 webkit-transition 上的防止闪烁

回答by Eugenio Enko

If the fonts are flickering use the following CSS:

如果字体闪烁,请使用以下 CSS:

html,body {
    -webkit-font-smoothing: antialiased;    
}

回答by Miljan Puzovi?

I noticed that after applying CSS3 transforms elements in Chrome looks a bit "crispy" and text unaligned. Solutions in Mathias answer have no effect on this. But here is strange thing - after I've applied webkit filters (i.e. -webkit-filter: opacity(0.99999);), elements rendered properly and letters in text are aligned. But after that those elements looks blured a bit. Maybe this have effect on your flickering.

我注意到在 Chrome 中应用 CSS3 转换元素后看起来有点“脆”并且文本未对齐。Mathias 答案中的解决方案对此没有影响。但这是奇怪的事情 - 在我应用了 webkit 过滤器(即-webkit-filter: opacity(0.99999);)之后,元素正确呈现并且文本中的字母对齐。但在那之后,这些元素看起来有点模糊。也许这对你的闪烁有影响。

回答by Garavani

First of all, thanks to the great solutions offered here. I always thought in the past there must be something wrong with my code. It wasn't. I also reasoned out the 2000px border for animations not running smoothly any longer. Thanks to you guys I now add

首先,感谢这里提供的出色解决方案。过去我一直认为我的代码一定有问题。不是。我还推断出 2000 像素的边框不再流畅运行的动画。感谢你们我现在补充

/*keep animation smooth in Safari above 2000px*/
@media ( min-width: 2000px ) {
    .boxContent {
        -webkit-backface-visibility: hidden;
    }
}  

I did this conditionally because, in fact, pictures don't render antialiased after adding the class. At another place I did

我有条件地这样做是因为,事实上,在添加类后,图片不会呈现抗锯齿。在另一个地方我做了

/*keep animation smooth in Safari above 2000px*/
.twothousand {
    -webkit-backface-visibility: hidden;
}  

and added and removed the additional class via JQuery. So the transitions are smooth and render after finished (removing the class again) A little complicated but it worked fine for me and finally makes animations in Safari above 2000px smooth. Great job, guys!!

并通过 JQuery 添加和删除附加类。所以过渡是平滑的,并在完成后渲染(再次删除类)有点复杂,但对我来说效果很好,最终使 Safari 中的动画在 2000px 以上变得平滑。干得好,伙计们!!

回答by Chet

An easy solution that solved all my problems was this:

解决我所有问题的简单解决方案是:

.app * {
  transform-style: preserve-3d;
}