CSS3 转换导致文本在 Safari 和 Firefox 中闪烁 Mac Yosemite

CSS3 Transform causing text to flicker in Safari and Firefox Mac Yosemite

我在 Safari 和 Firefox (Mac/Yosemite) 上遇到这个奇怪的问题,当鼠标悬停在转换元素上时,几乎所有页面上的文本都会闪烁。

示例 gif:(Firefox,Yosemite)

.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));
}

我试过以下方法:

将这些样式的所有可能组合添加到正文中,转换元素 and/or his parent

-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;

我完全不知道是什么原因造成的,也不知道我该如何解决!

-webkit-transform: translate3d(0, 0, 0);
-webkit-text-stroke: 0.35px;

这些代码是为支持多种浏览器而编写的。 试试 mozila

-moz-transform: translate3d(0, 0, 0);
-moz-text-stroke: 0.35px;

我发现这主要发生在已经转换的元素上(即:滑入的模态)。是否对任何父元素进行了转换?

网络上有大量针对基于 webkit 的浏览器的修复程序,但没有针对 Firefox 的修复程序。

啊哈,但是你试过了吗

.usp .icon {
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
}

http://jsfiddle.net/j04mayvb/4/

老实说,我不知道为什么会这样,但我可以看到它停止了 Safari 中 Fiddle 的闪烁。

OP 注意事项:您似乎至少了解这些概念中的大部分,但我在这个答案中为可能有类似问题的任何其他人提供了很多细节。

现代浏览器 运行 在具有专用 GPU(用于渲染图形的处理器)的计算机上,浏览器有时会将渲染网页的任务从您的 CPU("normal" 处理器)到 GPU。 CPU 和 GPU 各有优缺点——GPU 的本质是它可以非常有效地呈现 3 维变换,但可能无法像 [=47] 那样清晰地呈现纯文本=] 确实如此。

您的悬停效果正在使用您的浏览器认为适合硬件加速 GPU 渲染的转换(很可能由 scale(1.1) 转换触发),因此它已将渲染暂时转移到 GPU,同时悬停 animation/transition 发生。动画完成后,CPU 再次接管渲染。由于不同的硬件使用不同的渲染策略,当 GPU 负责时,文本看起来不同(不太清晰)。

不幸的是,我们(还)没有通过 CSS 明确控制硬件加速——浏览器会在需要时设置它。然而,我们可以做的是设置一些我们 怀疑 会将浏览器置于硬件加速 GPU 模式的属性。这里的理论是即使动画没有发生,我们也会将浏览器保持在 GPU 模式,这样我们就不会看到 "flicker".

此策略有一些缺点:当您的页面打开时,访问您网站的用户将体验到 RAM 内存使用量略微增加,而移动/笔记本电脑用户将体验到电池消耗略微增加。在没有专用 GPU 的设备上,不会触发硬件加速(但话又说回来,这些设备不会看到您看到的 "flicker")。

看起来您已经尝试通过将 scale(1.0) 属性 添加到未悬停的元素来执行此操作——我的最佳猜测是您的浏览器获得了 "clever" 并检测到此规则不执行任何操作并忽略它。触发硬件加速的最可靠方法通常是 Z 轴上的变换。尝试将您的转换更改为以下内容:

@include transform(scale(1.00001), translateZ(0.00001));

我没有使用值“1”和“0”,而是使用了无限接近的值;希望这会阻止浏览器获取 "clever" 并忽略规则。

我假设您的 Sass include 正在做供应商前缀。仔细检查最终输出是否不仅包含 -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);
}

在我这边,我没有在你的 fiddle 上体验到任何闪烁(我怀疑我的 browser/OS/hardware 配置认为二维尺度不适合GPU),所以我无法测试这段代码。但是,我经常使用类似的技术来解决类似的问题。

好的!

经过一周的测试、删除和添加 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/

好的!

所以,我遇到的问题是在一个自定义弹出窗口中,我使用 css 过渡对十字按钮产生了滚轮效果。但这导致弹出窗口出现闪烁问题。

访问各种在线门户网站后,我了解到过渡 属性:

webkit-backface-visibility: hidden;

在过渡元素上确实有效并停止了闪烁。但是在我的例子中,使用这个 属性 模糊了整个组件(弹出窗口),为了阻止它,我不得不在组件的根元素上使用另一个 属性:

webkit-transform: translate3d(0, 0, 0);

但是因为我在一个自定义弹出窗口中使用它,它已经在 y 方向上翻译了 -50% 以保持它在中心,我被限制不使用它。

玩了几天 css 属性并尝试了各种解决方案后,我得出结论,使用过渡元素的组件的总高度必须为 EVEN 如果是动态数据,我们需要调整边距和填充,使总高度保持 EVEN.

这解决了我的问题。只需确保总高度保持 EVEN 并相应地调整边距和填充。

希望它也能帮助到有需要的人。 :)