WebKit: Blurry text with css scale + translate3d
Asked Answered
C

8

61

I'm seeing an issue where Chrome and other WebKit browsers massively blur any css-scaled content that also has translate3d applied.

Here's a JS Fiddle: http://jsfiddle.net/5f6Wg/. (View in Chrome.)

.test {
  -webkit-transform: translate3d(0px, 100px, 0px);
}

.testInner
{
  /*-webkit-transform: scale(1.2);*/
  -webkit-transform: scale3d(1.2, 1.2, 1);
  text-align: center;
}
<div class="test">
  <div class="testInner">
    This is blurry in Chrome/WebKit when translate3d and scale or scale3d are applied.
  </div>
</div>

Are there any known workarounds for this? I get that in the simple example above, I could simply use translate rather than translate3d - the point here is to strip the code down to the bare essentials.

Cablegram answered 5/11, 2011 at 23:21 Comment(2)
i think this is fixed, doesnt look blurry to meSacrarium
A small addittion: in last Chrome i stucked with problem like when using not rounded values for translate3d. Rounding them fixed all blurr for me.Giza
M
36

Webkit treats 3d transformed elements as textures instead of vectors in order to provide hardware 3d acceleration. The only solution to this would be to increase the size of the text and downscaling the element, in essence creating a higher res texture.

See here: http://jsfiddle.net/SfKKv/

Note that antialiasing is still underpar (stems are lost) so I'm beefing up the text with a bit of text shadow.

Malapropism answered 7/11, 2011 at 15:37 Comment(3)
will it be much slower on mobile webkits then?Conferva
Great solution, looks a bit like a retina solution, but then for desktops. Love the idea, implementing it right now, super-props.Catchfly
Looks pretty awful to me in Chrome Version 54.0.2840.71 m (64-bit)Lorinalorinda
B
35

I found that using:

-webkit-perspective: 1000;

on the container of your font or icon set kept things crisp for me after experiment with the issue on Android nexus 4.2 for sometime.

Baseborn answered 27/6, 2013 at 8:45 Comment(4)
Dang, that did it! Along with -webkit-transform: translate3d(0,0,0). The letter forms were popping into place in an odd way at the end of the scale, and this fixed it. Tried everything else under the sun.Leak
Assume this is because those properties trigger GPU acceleration, also increasing performance of transitions on those elements! :)Baseborn
@SergeiBasharov i don't think the OP wanted a mobile solution. And on desktop it doesn't do anything. I upvoted this answer but that's all.Upi
I also needed -webkit-transform: translate3d(0,0,0)Mentally
N
28

A css filter effect is a graphical operation that allows to manipulate the appearance of any HTML element. Since Chromium 19 these filters are GPU accelerates to make them super fast.

CSS3 introduces a bunch of standard filter effects, one of them is the blur fitler:

-webkit-filter: blur(radius);

The ‘radius’ parameter affects how many pixels on the screen blend into each other, so a larger value will create more blur. Zero of course leaves the image unchanged.

Set the radius to 0 will force browser to use GPU calculation and force it to keep your html element unchanged. It's like applying an "hard edges" effects.

So the best solution for me in order to fix this blurry effect was to add this simple line of code:

-webkit-filter: blur(0);

There is also a known bug that only affects retina screens. (See here: Why doesn't blur(0) remove all text blur in Webkit/Chrome on retina screens?). So in order to make it works also for retina, I recommend to add this second line:

-webkit-transform: translateZ(0);
Niklaus answered 1/9, 2015 at 13:46 Comment(5)
please give some explanation to your answerSakai
As a note applying blur on the fly in dev tools seems to not have the same effect as it being there on page load. Not sure if it was just me but this may be the answer you are looking for, just reload the page.Cozza
After trying EVERYTHING else on a google search this was the fix. Thank you!Embolic
this worked for me! .modal { max-width: calc(100% - 50px); max-height: calc(100% - 50px); position: fixed; top: 50%; left: 50%; -ms-transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); transform: translate(-50%, -50%); -webkit-filter: blur(0); overflow: hidden; }Spatula
maoosi's answer used to work for me, but something seems to have changed as it doesn't work anymore in the latest Chrome?Lorinalorinda
L
6

Try this

 ...{
zoom:2;
-webkit-transform: scale(0.5);
transform: scale(0.5);
}

Or for a more exact approach you can call a javascript function to recalculate the transformation matrix by removing the decimal values of the matrix. see: https://mcmap.net/q/144668/-chrome-font-appears-blurry

Lineage answered 9/3, 2016 at 13:26 Comment(2)
for me just zoom: 1.005; worked well. no need to use scaleGrind
Unfortunately zoom cannot be animated, so attempting to use in in frames ends up looking choppy @JithinRajPRStrander
S
2

I came across this issue when using the isotope plugin (http://isotope.metafizzy.co/index.html) in combination with the zoom plugin (http://janne.aukia.com/zoomooz/). I built a jquery plugin to handle my case. I threw it up in a github repo in case anybody could benefit from it. - https://github.com/charleshimmer/jquery-hirestext.

So answered 11/9, 2012 at 20:10 Comment(0)
A
0

I used javascript to move the text 1px top and then with 100ms after, back 1px down. It's almost unperceptive and solved the problem completely cross-browser.

Anguiano answered 13/11, 2015 at 14:20 Comment(0)
D
-1
body {
-webkit-font-smoothing: subpixel-antialiased;
}

or I think you could put that on a specific element, but I was having problems with one element affecting the whole site.

I think it is a problem with custom font-face fonts.

Diver answered 31/7, 2012 at 21:26 Comment(2)
Appreciate that you're trying to add value here, but the JS Fiddle I provided doesn't use a custom font, and -webkit-font-smoothing doesn't seem to make any difference. Does it work for you in the Fiddle above?Cablegram
subpixel-antialiased font-smoothing is now the default in Chrome.Posthaste
T
-2

Webkit treats 3d transformed elements as textures instead of vectors in order to provide hardware 3d acceleration.

This has nothing to do with it. You'll notice that your aliasing problem can be fixed with the addition of duration and direction information (e.g. 0.3 linear). Your having a mare trying to render everything at runtime:

Same for the above ^

Tempa answered 30/1, 2012 at 17:12 Comment(2)
Sorry Tom, but I have no idea what you're referring to. Are you talking about adding an animation? (The intent was just to scale, not to animate anything.) If you modify the original JS Fiddle, maybe that would help.Cablegram
Since I am using a transition I added duration, and direction. The blur still persists.Basketwork

© 2022 - 2024 — McMap. All rights reserved.