How to prevent Webkit text rendering change during CSS transition

别说谁变了你拦得住时间么 提交于 2019-11-26 18:13:42

I think I found A solution:

-webkit-transform: translateZ(0px);

Forcing hardware acceleration on the parent element seems to solve the problem...

EDIT As commented, this hack disables font-smoothing and can degrade text rendering depending on your fonts, browser and OS!

UPDATE May 2018

-webkit-font-smoothing: subpixel-antialiased now has no effect in Chrome but in Safari it still improves things a great deal BUT ONLY ON RETINA. Without it in Safari on retina screens text is thin and insipid, whereas with it, text has the proper weight. But if you use this on non retina displays in Safari, (especially at light weight values) text is a disaster. Strongly recommend using a media-query :

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


Explicitly setting -webkit-font-smoothing: subpixel-antialiased is the best current solution if you wish to at least partially avoid the thinner antialiased text.

--tl;dr--

With both Safari and Chrome where the default font rendering uses subpixel-antialiasing, any CSS that forces GPU based rendering, like the suggestions above to use a transform using translateZ or even just a scale transition, will cause Safari and Chrome to automatically "give up" on subpixel-antialiased font smoothing and instead switch to just antialiased text, which looks a lot lighter and thinner, especially on Safari.

Other responses have focused on maintaining a constant rendering by simply setting or forcing font-smoothing to the thinner antiailiased text. To my eye using translateZ or backface hidden significantly degrades the quality of the text rendering and the best solution if you want the text to just stay consistent and you're OK with the thinner text is just to use -webkit-font-smoothing: antialiased. However, explicitly setting -webkit-font-smoothing: subpixel-antialiased does actually have some effect - the text does still change slightly and is just about visibly thinner during transitions rendered on the GPU but not as thin as it goes without this setting. So it looks like this at least partially prevents the switch to straight antiailiased text.

I've noticed that pretty much every time I'm having graphics issues (flickering/stuttering/choppiness/etc) due to a transition, using -webkit-backface-visibility: hidden; on the elements that are acting up tends to solve the problem.

To prevent text rendering changes due to hardware-acceleration, you can either:

  1. Set all text to -webkit-font-smoothing: antialiased. This means text is thinner and not sub-pixel antialiased.

  2. If you want text which is being affected by hardware-acceleration to be sub-pixel antialiased (the default kind of font smoothing), then putting that text inside an input, without borders and disabled, will keep that sub-pixel antialiased (at least on Chrome on Mac OS X). I have not tested this on other platforms, but if sub-pixel antialiasing is important, you can at least use this trick.

eleclair

If you're using Firefox on a Mac you'll want to use the following css to fix the issue.

-moz-osx-font-smoothing: grayscale;

More on this at Webfont Smoothing and Antialiasing in Firefox and Opera

This is what worked for me. Hope it helps. Found in other stackoverflow post.

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

To prevent the rendering change you need to set font-smoothing: antialiased (or none).

The browser disabling subpixel font rendering is likely a side-effect of hardware acceleration. When the background you are rendering against is constantly shifting, the text cannot be rendered on a separate layer, as each frame must be checked against all background layers. This could severely degrade performance.

Apple often disable subpixel font-smoothing on their own sites.

In addition to the above solutions (-webkit-transform: translateZ(0px) on the element, and -webkit-font-smoothing: antialiased on the page) some elements may still behave badly. For me it was placeholder text in an input element: For this, use position:relative

I had the same problem. Read it carefully:

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.

none of the solutions above seemed to work. However, setting (things like)

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

on the element that has the animation did work.

By taking the animated element to the GPU layer you take it out of the normal flow of the page rendering (things like z-index will not work anymore too, for example). As a side effect, the animation and the rest of the page wont influence eachother anymore.

If it effects your font rendering, it only does so for the animated element, ofcourse. I don't see the difference in my Chrome.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!