如何防止CSS过渡期间Webkit文本呈现更改


81

我正在使用CSS转换在CSS转换状态之间进行转换(基本上是在转换元素的比例)。我注意到当元素过渡时,页面上的其余文本(在Webkit中)倾向于稍微改变其呈现方式,直到过渡完成为止。

小提琴:http : //jsfiddle.net/russelluresti/UeNFK/

我还注意到在我的标头上没有发生这种情况,标头上具有-webkit-font-smoothing: antialiased属性/值对。因此,我想知道,是否有任何方法可以使文本保持其默认外观(字体平滑的“自动”值)并且在过渡期间不更改渲染。

我尝试过显式设置文本以使用“自动”值,但这没有任何作用。我还应注意,将字体平滑设置为“无”也可以防止过渡期间渲染闪烁。

任何帮助表示赞赏。

编辑1

我应该注意,我使用的是OSX。在Parallels上的Chrome浏览器中测试时,我没有看到两个不同的段落的行为有所不同,因此这可能是Mac独有的问题。


21. Safari版本为6。这两种浏览器都存在,这使我认为它是Webkit,而不是浏览器。
RussellUresti 2012年

抗锯齿和抗锯齿的段落都表现出相同的行为。chrome版本23.0.1270.0金丝雀| 21.0.1180.89 m | 5.17野生动物园

我猜您正在使用Chrome的开发版。不过,操作系统可能在其中发挥了作用。我将编辑该问题,以注意我正在使用OSX。
RussellUresti 2012年

1
我完全不知道为什么会这样,但是添加了“ -webkit-transform:translateZ(0);” 到'.antialiased {}似乎可以解决此问题。如果将其添加到“ p {}”,它甚至可以工作。由于我无法解释为什么这样做有效,因此提供它作为答案并不适合。希望有帮助!
Christofer Vilander 2012年

@Christofer这使它们一致-但却使它们全部显得抗锯齿(它们都是较细的文字)。我正在尝试使未抗锯齿的文本(第一段)保持其默认样式(该外观比抗锯齿的文本大胆)。
RussellUresti 2012年

Answers:


83

我想我找到了一个解决方案:

-webkit-transform: translateZ(0px);

在父元素上强制硬件加速似乎可以解决问题...

编辑 正如评论所述,此hack会禁用字体平滑功能,并且可能会根据您的字体,浏览器和操作系统降低文本渲染效果!


尝试了字体平滑处理,但是没有用。尝试了一下,效果很好
locrizak

这并没有为我说明的问题提供理想的结果,但这有助于解决我遇到的其他CSS过渡问题(例如,在过渡元素中隐藏/显示内容时出现奇怪的闪烁文本)。
RussellUresti 2013年

3
-webkit-font-smoothing:antialiased;对我不起作用 和-webkit-backface-visibility:hidden; 作品。积分何去何从stackoverflow.com/questions/11589985/...
˚FLekschas

+1很棒,这是解决我所处情况的唯一方法
Larry

4
首先,这将禁用字体平滑。因此,您在过渡开始时没有字体平滑,过渡时没有字体平滑,而在结束时也没有字体平滑。因此,没有字体平滑变化,也没有字体平滑变化。
yunzen 2013年

45

2020年8月更新

您不再需要通过媒体查询来定位Safari以启用亚像素字体平滑。默认值很好。

但是,尽管默认情况下它使用亚像素字体平滑,但是对于希望寻找一致的文本呈现的人来说,Chrome字体平滑的美中不足之处

  1. 这是Chrome在深色背景上呈现的浅色文字 黑暗中的光
  2. 这是Chrome在浅色背景上呈现深色文字的效果 黑暗亮

在上面的字母e中查看整体的大小。与浅色背景上的深色文本(具有相同的css字体样式)相比,深色背景上的浅色文本具有明显可观的重量。

对于尊重用户的暗/亮主题设置的网站,一种解决方案是使用仅限于暗模式的媒体查询来定位Chrome,然后将其切换为非亚像素平滑处理,如下所示:

@media screen
and (-webkit-min-device-pixel-ratio: 0)
and (min-resolution: 0.001dpcm)
and (prefers-color-scheme: dark) {
  body {
    -webkit-font-smoothing: antialiased;
  }
}

结果 :

黑暗亮亮暗抗锯齿

无论是在暗处还是在暗处,都具有更一致的文本粗细。

查看之前和之后的并排比较: 黑暗中的光亮暗抗锯齿

-

2018年5月更新

-webkit-font-smoothing: subpixel-antialiased现在在Chrome中没有效果,但在Safari中,它仍然只能在RETINA上进行很多改进。在视网膜屏幕上的Safari中,如果没有它,文本将变得很薄且平淡,而有了它,文本将具有适当的重量。但是,如果您在Safari的非视网膜显示器上使用此功能(尤其是在轻量级时),文本将是一场灾难。强烈建议使用媒体查询:

@media screen and (-webkit-min-device-pixel-ratio: 2) {
  body {
    -webkit-font-smoothing: subpixel-antialiased;
  }
}

-webkit-font-smoothing: subpixel-antialiased如果希望至少部分地避免使用较薄的抗锯齿文字,则显式设置是当前的最佳解决方案。

--tl;博士-

在Safari和Chrome中,默认字体渲染均使用亚像素抗锯齿功能,任何强制基于GPU渲染的CSS(例如上述建议使用通过translateZ进行的转换甚至只是比例转换)都会导致Safari和Chrome自动“放弃” ”使用亚像素抗锯齿字体平滑,而是切换为仅抗锯齿文本,它看起来要轻薄得多,尤其是在Safari上。

其他响应集中在通过简单地设置或强制对较薄的抗锯齿文本进行字体平滑来保持恒定的呈现。在我看来,使用translateZ或隐藏的背面会大大降低文本渲染的质量,如果您只希望使文本保持一致并且可以使用较薄的文本,则最好的解决方案是使用-webkit-font-smoothing: antialiased。但是,显式设置-webkit-font-smoothing: subpixel-antialiased实际上确实会产生一些效果-文本仍然会略有变化,并且在GPU上渲染的过渡过程中,文本明显变薄,但没有设置时变薄。因此,这看起来至少部分阻止了改用平直的抗锯齿文字。


2
谢谢你写的好!
丹尼斯·戈尔巴乔夫

2
这是最好的解决方案。其他所有参数都会降低文本呈现效果,这是OP专门要求避免的内容
fregante

我的救生员!谢谢。避免在CSS过渡后突然切换到子像素渲染。至少在不透明度过渡的情况下,即使在过渡期间,这也会使字体保持(理论上始终是默认值)子像素渲染。大!
Garavani 2014年

对我们最好的解决方案!谢谢
2015年

谢谢,我一年多以前就碰到了这个,忘了所有。这是唯一为我解决了上述问题的解决方案。
伊恩·柯林斯

20

我已经注意到,几乎每当我因过渡而遇到图形问题(闪烁/卡顿/抖动/等)时,都可以使用-webkit-backface-visibility:hidden;。在起作用的元素上倾向于解决问题。


3
这是(当前)正确的答案。据我所知,webkit-font-smoothing不久前已被删除,应该再次添加,但目前在最新版本的Chrome中不适用于我。translateZ技巧似乎也不再起作用。我想这随时都可能改变。:/
Mantriur

3
这使一些文字对我来说变得模糊。
约翰·

8

为了防止由于硬件加速而导致文本呈现更改,您可以:

  1. 将所有文本设置为-webkit-font-smoothing:抗锯齿。这意味着文本较细且没有亚像素抗锯齿。

  2. 如果要对受硬件加速影响的文本进行亚像素抗锯齿(字体平滑的默认类型),则将该文本放入输入中(无边框和禁用)将使该亚像素抗锯齿(至少在Mac OS X上的Chrome上)。我尚未在其他平台上对此进行过测试,但是如果亚像素抗锯齿非常重要,则至少可以使用此技巧。


我已经在Win8.1和Chrome 47上测试了选项2(带输入元素的技巧),但是它不起作用。
2015年



1

为防止渲染更改,您需要设置font-smoothing: antialiased(或none)。

浏览器禁用亚像素字体渲染可能是硬件加速的副作用。当您要渲染的背景不断变化时,无法在单独的图层上渲染文本,因为必须对照所有背景图层检查每一帧。这可能会严重降低性能。

苹果通常会在自己 网站上禁用亚像素字体平滑功能。


将字体平滑设置为抗锯齿的问题是文本看起来不像我想要的那样。我希望将字体平滑设置为“自动”(大胆外观)的视觉效果-但是,当您执行此操作时,文本将在任何过渡期间移动。因此,我的目标是始终保持“自动”的大胆外观。
RussellUresti 2012年

1
您可以通过不使用硬件加速来解决它。在jQuery中使用计时器,并手动进行过渡(无需CSS过渡)。我不确定我会推荐它,但是性能和平滑度会更差。
亨里克2012年

没错,我可以使用jQuery对其进行动画处理……如果没有其他解决方案,那可能是唯一的解决方案。
RussellUresti 2012年

1

除了上述解决方案(-webkit-transform: translateZ(0px)在元素上和-webkit-font-smoothing: antialiased在页面上)以外,某些元素可能仍然表现不佳。对我来说,它是输入元素中的占位符文本:为此,请使用position:relative


-1

我有同样的问题。请仔细阅读:

我注意到当元素过渡时,页面上其余文本(在Webkit中)倾向于稍微改变其呈现方式,直到过渡完成为止。

上面的解决方案似乎都不起作用。但是,设置(类似的东西)

#myanimation { -webkit-transform: translateZ(0px); }

具有动画效果的元素上起作用。

通过将动画元素带到GPU层,可以将其从页面渲染的正常流程中移除(例如,像z-index这样的东西也将不再起作用)。副作用是,动画和页面的其余部分不再相互影响。

如果影响字体渲染,则仅对动画元素起作用。我没有看到Chrome的区别。


我站得住了。我确实在页面的其余部分以及未应用translateZ(0)的地方看到了字体渲染的更改。
commonpike 2014年

当我的字体图标变得模糊时,这是唯一对我有用的东西。将转换应用于正在制作动画的部分,即可解决问题。
比尔

杜德(Dude),两年前就已经回答了。就在上方...完全相同的答案/代码。
NiCk Newman

是的,我唯一的一点是你必须把-webkit-transform具有动画元素,以防止呈现的变化在页面上的其他元素。但正如所评论的那样,它工作了一段时间,但是当我稍后更改页面的某些位时,它停止了工作。
commonpike
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.