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 并相应地调整边距和填充。
希望它也能帮助到有需要的人。 :)
我在 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 并相应地调整边距和填充。
希望它也能帮助到有需要的人。 :)