Safari changing font weights when unrelated animat

2019-01-12 23:54发布

I'm using css animations on my page and Safari seems to change unrelated font weights elsewhere on the page when animations are running. Any idea why this happens? All other browsers work fine, include webkit ones like Chrome.

I've detailed the bug in a video here - http://www.screenr.com/gZN8

The site is also here - http://airport-r7.appspot.com/ but it might keep changing rapidly.

I'm using compass (@transition-property, @transition-duration) on the arrow icons. No transitions applied on the heading that's flashing. On a Mac - so it might be the hardware acceleration, but I'm still trying to figure it out.

3条回答
Deceive 欺骗
2楼-- · 2019-01-13 00:01

Apparently, that's the price you pay for hardware acceleration: all text momentarily turns into images, which causes the drop in render quality.

However, applying html {-webkit-font-smoothing: antialiased} to turn off the sub-pixel anti-aliasing makes this problem go away. That's what I'm doing for now.

UPDATE: Since then, I've also come to learn that this happens only when the browser can't be sure if the section being animated is going to affect the text. This can usually be handled by having the text above (higher z-index than) the elements being animated, and/or making sure the text has a fully opaque background.

查看更多
聊天终结者
3楼-- · 2019-01-13 00:17

I've faced this issue numerous times and have had success adding the following css to the animated element:

z-index: 60000;
position: relative;

It seems it needs both z-index and position to be effective. In my case I was using it with Font Awesome animated spinners.

查看更多
疯言疯语
4楼-- · 2019-01-13 00:21

When you trigger GPU compositing (eg, through CSS animation), the browser sends that element to the GPU, but also anything that would appear on top of that element if its top/left properties were changed. This includes any position:relative elements that appear after the animating one.

The solution is to give the animating element position:relative and a z-index that puts it above everything else. That way you get your animation but keep the (superior IMO) sub-pixel font rendering on unrelated elements.

Here's a demo of the problem and solution http://www.youtube.com/watch?v=9Woaz-cKPCE&hd=1

Update: Newer versions of Chrome retain sub-pixel antialiasing on GPU composited elements as long as the element has no transparency, eg has a background with no transparent or semi-transparent pixels. Note that things like border-radius introduce semi-transparent pixels.

查看更多
登录 后发表回答