83

I'm using CSS transitions to transition between CSS transformed states (basically transitioning the scale of an element). I notice that when the element is transitioning, the rest of the text on the page (in Webkit) tends to slightly alter its rendering until the transition is done.

Fiddle: http://jsfiddle.net/russelluresti/UeNFK/

I also noticed that this does not occur on my headers, which have the -webkit-font-smoothing: antialiased property/value pair on them. So, I'm wondering, is there any way to have the text maintain its default look (the "auto" value for font-smoothing) and not alter rendering during a transition.

I've tried explicitly setting the text to use the "auto" value, but that doesn't do anything. I should also note that setting font-smoothing to "none" also prevents the rendering blink during transition.

Any help is appreciated.

Edit 1

I should note that I am on OS X. While looking at my test in Chrome on Parallels, I did not see the two different paragraphs behaving differently, so this may be an issue exclusive to Macs.

4

9 回答 9

84

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

-webkit-transform: translateZ(0px);

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

编辑 正如评论的那样,这个 hack 会禁用字体平滑,并且会根据您的字体、浏览器和操作系统降低文本渲染!

于 2012-10-10T13:19:20.240 回答
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 或 backface hidden 会显着降低文本渲染的质量,如果您希望文本保持一致并且您可以接受较薄的文本,那么最好的解决方案就是使用-webkit-font-smoothing: antialiased. 然而,显式设置-webkit-font-smoothing: subpixel-antialiased确实有一些效果 - 文本仍然略有变化,并且在 GPU 上呈现的过渡期间明显变薄,但没有没有此设置时那么薄。所以看起来这至少部分地阻止了切换到直接抗锯齿文本。

于 2014-01-15T11:23:55.333 回答
20

我注意到几乎每次由于过渡而出现图形问题(闪烁/口吃/断断续续/等)时,使用 -webkit-backface-visibility: hidden; 在起作用的元素上往往会解决问题。

于 2013-07-16T20:03:39.987 回答
8

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

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

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

于 2013-03-06T06:59:29.460 回答
5

如果您在 Mac 上使用 Firefox,您将需要使用以下 css 来解决此问题。

-moz-osx-font-smoothing: grayscale;

更多信息请参阅 Firefox 和 Opera 中的 Webfont Smoothing and Antialiasing

于 2015-04-03T19:25:56.717 回答
3

这对我有用。希望能帮助到你。在其他 stackoverflow 帖子中找到。

-webkit-font-smoothing:antialiased;
-webkit-backface-visibility:hidden;
于 2017-04-24T15:39:04.587 回答
1

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

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

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

于 2012-09-22T12:11:21.830 回答
1

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

于 2014-05-15T16:57:09.503 回答
-1

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

我注意到当元素转换时,页面上的其余文本(在 Webkit 中)往往会稍微改变其呈现,直到转换完成。

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

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

在具有动画的元素上确实有效。

通过将动画元素带到 GPU 层,您可以将其脱离页面渲染的正常流程(例如,z-index 之类的东西也不再起作用)。作为副作用,动画和页面的其余部分将不再相互影响。

如果它影响你的字体渲染,当然它只对动画元素起作用。我在我的 Chrome 中看不到有什么不同。

于 2014-04-04T22:21:37.093 回答