CSS3 转换导致文本在 Safari 和 Firefox Mac Yosemite 中闪烁
Posted
技术标签:
【中文标题】CSS3 转换导致文本在 Safari 和 Firefox Mac Yosemite 中闪烁【英文标题】:CSS3 Transform causing text to flicker in Safari and Firefox Mac Yosemite 【发布时间】:2015-08-18 16:22:14 【问题描述】:我在 Safari 和 Firefox (Mac/Yosemite) 上遇到了这个奇怪的问题,当鼠标悬停在转换元素上时,几乎所有页面上的文本都会闪烁。
示例 gif:(Firefox、优胜美地)
.usp
//USP has an icon that is defined below
opacity: .4;
@include transition(all .3s ease-in-out);
&:hover
opacity: 1;
@include transition(all .3s ease-in-out);
.icon
@include transform(scale(1.1));
@include transition(all 1.7s ease-in-out);
// :hover
.usp .icon
display: block;
height: 75px;
width: 75px;
// Insert background-image sprite (removed from this example)
@include transition(all .3s ease-in-out);
@include transform(scale(1.0));
我尝试了以下方法:
将这些样式的所有可能组合添加到主体、转换元素和/或其父元素
-webkit-transform-style:preserve-3d;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-filter: opacity(.9999);
-webkit-font-smoothing: antialiased;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
-webkit-font-smoothing: subpixel-antialiased;
-webkit-text-stroke: 0.35px;
如果(以下样式)应用于正文,问题在 Safari 中得到解决,但在 Firefox 中没有得到解决,因为它不是 webkit 浏览器。
-webkit-transform: translate3d(0, 0, 0);
-webkit-text-stroke: 0.35px;
我真的不知道是什么原因造成的以及如何解决它!
【问题讨论】:
请在jsfiddle.net上添加代码sn-p。 我已经尽可能地尝试创建一个小提琴。 (因为整个网站使用了很多样式,我不能只是复制/粘贴一些东西)。不知何故,这个小提琴在 FF 中确实有效,而不是在 Safari 中。 jsfiddle.net/Mr_recci/j04mayvb/2 @MrRecci 因为 jsfiddle 不支持 sass,我认为你在那个小提琴中的一些样式丢失了。 @WoodrowBarlow 它确实支持 SCSS,因为它在右上角显示“scss” @MrRecci 哇!这很酷。我从来不知道。 【参考方案1】:好的!
经过一周的测试、删除和添加 CSS 规则,我终于找到了解决问题的解决方案。我最初在 Firefox 39 和 Safari 9 中都遇到了这个问题,但 Firefox 用最新的更新神秘地修复了自己。然而,Safari 没有。问题与页面上元素的 3D 渲染有关。我尝试缩放的元素必须转换为 3D 上下文,页面上的闪烁元素在 2D 和 3D 之间切换,正如 @Woodrow-Barlow 在其他答案中所解释的那样。
通过添加
-webkit-transform: translate3d(0, 0, 0);
到闪烁的元素,从而在页面加载时以 3D 呈现它们,它们不再需要切换!
编辑 1:对于在其他浏览器中遇到此问题的人,请查看 CSS 'will-change' 属性: https://dev.opera.com/articles/css-will-change-property/
【讨论】:
完美,修复了在 Firefox 和 Chrome 中有效但在 Safari 中无效的不透明度过渡的相同问题。 (我认为 Chrome 会表现出类似的行为,但不是。)【参考方案2】:OP 的注意事项:您似乎至少了解这些概念中的大部分,但我在此答案中为可能遇到类似问题的其他人提供了很多细节。 p>
在具有专用 GPU(用于渲染图形的处理器)的计算机上运行的现代浏览器中,浏览器有时会将渲染网页的任务从您的 CPU(“普通”处理器)转移到 GPU。 CPU 和 GPU 各有优缺点 - GPU 的本质是它可以非常高效地渲染 3 维转换,但可能无法像 CPU 那样清晰地渲染纯文本。
您的悬停效果正在使用您的浏览器认为适合硬件加速 GPU 渲染的转换(很可能由 scale(1.1)
转换触发),因此它在悬停动画/转换时将渲染临时转移到 GPU发生。动画完成后,CPU 再次接管渲染。由于不同的硬件使用不同的渲染策略,当 GPU 负责时,文本看起来会有所不同(不太清晰)。
不幸的是,我们(还)没有通过 CSS 明确控制硬件加速——浏览器可以随时设置。然而,我们可以做的是设置一些我们怀疑会将浏览器置于硬件加速 GPU 模式的属性。这里的理论是,即使动画没有出现,我们也会将浏览器保持在 GPU 模式,这样我们就不会看到“闪烁”。
此策略有一些缺点:访问您网站的用户会在您的页面打开时体验到 RAM 内存使用量略有增加,而移动/笔记本电脑用户将体验到电池消耗量略有增加。在没有专用 GPU 的设备上,不会触发硬件加速(但话又说回来,这些设备不会看到您所看到的“闪烁”)。
您似乎已经尝试通过将scale(1.0)
属性添加到未悬停的元素来执行此操作——我最好的猜测是您的浏览器变得“聪明”并检测到此规则什么都不做并忽略了它。触发硬件加速的最可靠方式通常是在 Z 轴上进行转换。尝试将您的转换更改为以下内容:
@include transform(scale(1.00001), translateZ(0.00001));
我没有使用值“1”和“0”,而是使用无限接近的值;希望这将防止浏览器变得“聪明”并忽略规则。
我假设你的 Sass 包含在做供应商前缀。仔细检查最终输出是否不仅包含-webkit-transform:
和-moz-transform:
,而且还包含不带前缀的transform:
语法。如果您想确定(出于调试目的),只需手动输入:
.usp .icon
transform: scale(1.00001), translateZ(0.00001);
-webkit-transform: scale(1.00001), translateZ(0.00001);
-moz-transform: scale(1.00001), translateZ(0.00001);
就我而言,从你的小提琴开始,我没有遇到任何闪烁(我怀疑我的浏览器/操作系统/硬件配置不认为二维比例适合 GPU),所以我'我无法测试这段代码。但是,我经常使用类似的技术来解决类似的问题。
【讨论】:
谢谢!关于渲染的解释很完美,并给了我一些关于在哪里寻找答案的指示。然而,提供的解决方案并没有帮助。添加 -webkit-transform: translate3d(0, 0, 0) 为我修复了它。 (见我的另一个答案) 奇怪。 translate3d 只是一个简写,包括 translateX、translateY 和 translateZ。无论如何,很高兴你把它修好了。【参考方案3】:啊,但是你试过了吗
.usp .icon
-webkit-transform: translateZ(0);
transform: translateZ(0);
http://jsfiddle.net/j04mayvb/4/
老实说,我不知道为什么会这样,但我可以看到它停止了 Safari 中 Fiddle 的闪烁。
【讨论】:
奇怪的是,这在 Safari 中对我不起作用。我添加了其他前缀,它在 Firefox 中也不起作用。 i.imgur.com/7wGUDFE.gifv 你能观察我发布的 jsfiddle 链接吗?或者这也在 Safari 中闪烁? @MrRecci 除了 webkit 之外,您是否尝试过包括无前缀转换? 好吧,如果我的小提琴在 Safari 中停止闪烁,并且在 Firefox 中的小提琴中没有发生闪烁,那么还能做什么呢?我应该测试什么?【参考方案4】:好的!
所以,我面临的问题是在一个自定义弹出窗口中,我使用 css 过渡对十字按钮产生了滚轮效果。但这会导致弹出窗口出现闪烁问题。
在访问了各种在线门户之后,我知道了过渡属性:
webkit-backface-visibility: hidden;
在过渡元素上确实有效并停止闪烁。但是在我的情况下,使用这个属性会模糊整个组件(弹出窗口),为了阻止这种情况,我不得不在组件的根元素上使用另一个属性:
webkit-transform: translate3d(0, 0, 0);
但由于我在自定义弹出窗口中使用它,该弹出窗口已经在 y 方向上平移了 -50% 以使其保持在中心,因此我被限制不使用它。
在玩了几天css属性并尝试了各种解决方案之后,我得出一个结论,即使用过渡元素的组件的总高度必须是EVEN,如果是动态数据,我们需要调整边距和内边距,使总高度保持EVEN。
这解决了我的问题。只需确保总高度保持 EVEN 并相应地调整边距和填充。
希望它也能帮助有需要的人。 :)
【讨论】:
【参考方案5】:-webkit-transform: translate3d(0, 0, 0);
-webkit-text-stroke: 0.35px;
这些代码是为支持多浏览器而编写的。 在 mozila 上试试这个
-moz-transform: translate3d(0, 0, 0);
-moz-text-stroke: 0.35px;
【讨论】:
谢谢,我已经尝试将它们添加到正文和转换元素中。还是同样的问题。带有 -moz 前缀的文本笔划不存在 你能不能在这里做一个sn-p,最好能知道问题。 我已经尽可能地尝试创建一个小提琴。 (因为整个网站使用了很多样式,我不能只是复制/粘贴一些东西)。不知何故,这个小提琴在 FF 中确实有效,而不是在 Safari 中。 jsfiddle.net/Mr_recci/j04mayvb/2【参考方案6】:我发现这主要发生在已转换的元素上(即:滑入的模态)。是否对任何父元素进行了转换?
网络上有大量针对基于 webkit 的浏览器的修复,但没有针对 Firefox。
【讨论】:
不!父母只是普通的 div,没有任何翻译或转换。我也找到了(并尝试过)修复程序,但它们都是 hacky。以上是关于CSS3 转换导致文本在 Safari 和 Firefox Mac Yosemite 中闪烁的主要内容,如果未能解决你的问题,请参考以下文章
带有 Safari 的 iPhone 无法正确解释 @media
jScrollPane 在 Safari 中的视频上导致文本失真