如何防止在 CSS 转换过程中 Webkit 文本呈现的变化

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

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

我还注意到,这种情况不会发生在我的头上,它们上面有 -webkit-font-smoothing: antialiased属性/值对。所以,我想知道,有没有什么方法可以让文本保持它的默认外观(字体平滑的“ auto”值) ,并且在过渡期间不改变渲染效果。

我已经尝试显式地设置文本使用“ auto”值,但这没有任何作用。我还应该注意的是,设置字体平滑为“无”也防止渲染眨眼在过渡期间。

感谢你的帮助。

编辑1

我应该注意到我在 OS X 上。当我在并行浏览器上看我的测试时,我没有看到两个不同的段落有不同的表现,所以这可能是 Mac 独有的问题。

69920 次浏览

要防止呈现更改,需要设置 font-smoothing: antialiased(或 none)。

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

苹果经常在 他们的 自己的站点上禁用亚像素字体平滑。

我想我找到解决办法了:

-webkit-transform: translateZ(0px);

强制父元素上的硬件加速 似乎解决了这个问题... ..。

剪辑 如上所述,这种黑客禁用字体平滑,可以降低文本渲染取决于您的字体,浏览器和操作系统!

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

  1. 将所有文本设置为-webkit-font- 平滑: 反锯齿。这意味着文本更薄,而不是亚像素反锯齿。

  2. 如果你希望受硬件加速影响的文本具有亚像素抗锯齿效果(默认的字体平滑效果) ,那么将文本放入输入框中,不带边框且禁用,将保持亚像素抗锯齿效果(至少在 Mac OS X 上的 Chrome 上是这样)。我还没有在其他平台上测试过,但是如果亚像素反锯齿很重要,那么至少可以使用这个技巧。

我已经注意到,几乎每次我有图形问题(闪烁/结巴/断断续续/等) ,由于过渡,使用-webkit-backface-visible: hide; 对元素的行为往往解决问题。

更新日期: 2020年8月

您不再需要使用媒体查询来瞄准 Safari 来启用子像素字体平滑。

然而 ,虽然默认使用亚像素字体平滑,但是对于任何寻找 文本的一致呈现的人来说,铬的字体平滑中有一个重要的 美中不足

  1. 这是 Chrome 在深色背景上渲染的浅色文本light on dark
  2. 这是 Chrome 在浅色背景上渲染的深色文本dark on light

看上面字母 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;
}
}

结果是:

dark on lightlight on dark antialiased

一个更加一致的文本权重,无论是否渲染光明上的黑暗或黑暗上的光。

你可在此查阅前后比较: light on darklight on dark 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是当前的最佳解决方案。

——医生——

对于 Safari 和 Chrome 来说,默认的字体渲染都使用了亚像素反锯齿效果,任何基于 GPU 的 CSS 强制渲染,比如上面提到的使用 transateZ 变换,甚至只是一个缩放过渡,都会导致 Safari 和 Chrome 自动“放弃”亚像素反锯齿效果的字体平滑,转而使用反锯齿效果的文本,这样看起来更轻更薄,特别是在 Safari 上。

其他的回应则集中在通过简单地设置或强制字体平滑到较薄的反锯齿文本来保持一个恒定的渲染。在我看来,使用 transateZ 或者背面隐藏显著降低了文本渲染的质量,如果你想让文本保持一致,并且你可以接受较薄的文本,那么最好的解决方案就是使用 -webkit-font-smoothing: antialiased。然而,显式设置 -webkit-font-smoothing: subpixel-antialiased实际上确实有一些效果-文本仍然略有变化,只是在 GPU 上渲染的过渡期间明显变薄了,但没有没有这个设置时那么薄。所以看起来这至少部分地阻止了切换到直接的抗锯齿文本。

我也有同样的问题,仔细读一下:

我注意到当元素转换时,文本的 < strong > 其余部分 在页面 上(在 Webkit 中)倾向于稍微改变它的渲染,直到 过渡期结束了。

以上的解决方案似乎都不管用。然而,设置(例如)

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

有动画确实起作用的元素上。

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

如果它影响你的字体渲染,它只会影响动画元素,当然。我看不出我的 Chrome 有什么不同。

除了以上的解决方案(元素上的 -webkit-transform: translateZ(0px),页面上的 -webkit-font-smoothing: antialiased) ,一些元素仍然可能表现得很糟糕。对于我来说,它是输入元素中的占位符文本: 对于这一点,使用 position:relative

如果你在 Mac 上使用 Firefox,你可以使用下面的 css 来解决这个问题。

-moz-osx-font-smoothing: grayscale;

详情请看 在 Firefox 和 Opera 中使用 Webfont 平滑和 Antialiasing频道

这是什么为我工作。希望它有所帮助。发现在其他堆栈溢出后。

-webkit-font-smoothing:antialiased;
-webkit-backface-visibility:hidden;