Blurry text after using CSS transform: scale(); in Chrome

204,019

Solution 1

I have had this problem a number of times and there seems to be 2 ways of fixing it (shown below). You can use either of these properties to fix the rendering, or both at the same time.

Backface visibility hidden fixes the problem as it simplifies the animation to just the front of the object, whereas the default state is the front and the back.

backface-visibility: hidden;

TranslateZ also works as it is a hack to add hardware acceleration to the animation.

transform: translateZ(0);

Both of these properties fix the problem that you are having but some people also like to add

-webkit-font-smoothing: subpixel-antialiased;

to their animated object. I find that it can change the rendering of a web font but feel free to experiment with that method too.

Solution 2

After trying everything else here with no luck, what finally fixed this issue for me was removing the will-change: transform; property. For some reason it caused horribly blurry looking scaling in Chrome, but not Firefox.

Solution 3

To improve the blurriness, esp. on Chrome, try doing this:

transform: perspective(1px) translateZ(0);
backface-visibility: hidden;

UPDATE: Perspective adds distance between the user and the z-plane, which technically scales the object, making the blurriness seem 'permanent'. The perspective(1px) above is like duck-tape because we're matching the blurriness we're trying to solve. You might have better luck with the css below:

transform: translateZ(0);
backface-visibility: hidden;

Solution 4

I found that adjusting the scale ratio helped slightly.

Using scale(1.048) over (1.05) seemed to generate a better approximation to a whole-pixel font size, reducing the sub-pixel blurring.

I also used translateZ(0) which seems to adjust Chrome's final rounding step in the transform animation. This is a plus for my onhover usage because it increases speed and reduces visual noise. For an onclick function however, I wouldn't use it because, the transformed font doesn't appear to be as crispy.

Solution 5

Instead of

transform: scale(1.5);

using

zoom : 150%;

fixes the text blurring problem in Chrome.

Share:
204,019

Related videos on Youtube

Ryan O'Rourke
Author by

Ryan O'Rourke

Updated on April 23, 2022

Comments

  • Ryan O'Rourke
    Ryan O'Rourke about 2 years

    Seems like there has been a recent update to Google Chrome that causes blurry text after doing a transform: scale(). Specifically I'm doing this:

    @-webkit-keyframes bounceIn {
      0% {
        opacity: 0;
        -webkit-transform: scale(.3);
      }
    
      50% {
        opacity: 1;
        -webkit-transform: scale(1.05);
      }
    
      70% {
        -webkit-transform: scale(.9);
      }
    
      100% {
        -webkit-transform: scale(1);
      }
    }
    

    If you visit http://rourkery.com in Chrome, you should see the problem on the main text area. It didn't used to do this and it doesn't seem to effect other webkit browsers (like Safari). There were some other posts about people experiencing a similar issue with 3d transforms, but can't find anything about 2d transforms like this.

    Any ideas would be appreciated, thanks!

    • Nolonar
      Nolonar over 11 years
      Just visited the site using Firefox and IE 10, don't see the problem. If it's limited to Chrome, you might need to wait for Google to fix it themselves.
    • vsync
      vsync about 11 years
      I don't see any blurring...i'm on Chrome v25/PC
    • raj_n
      raj_n about 11 years
      I've come across this problem earlier too, as Nolonar mentioned we'll have to wait for Google to fix it.
    • Bangkokian
      Bangkokian about 5 years
      Not a solution, but I have noticed that the issue only occurs for me when I use CSS optimizeLegibility.
    • Timothy003
      Timothy003 over 4 years
      Link is broken.
    • dziku86
      dziku86 about 3 years
      html5rocks.com/en/tutorials/internals/antialiasing-101 Anyone who suffers from blurry text should read this old article by Paul Lewis. In short it's mainly all about Subpixel antialiasing quirks.
  • Michael Martin-Smucker
    Michael Martin-Smucker about 10 years
    These techniques all seem to improve things, but I still can't get Chrome to the same level of clarity that I see in Firefox.
  • Kevin
    Kevin about 9 years
    It can help but also introduces other issues, like white border lines being introduced sometimes
  • Naisheel Verdhan
    Naisheel Verdhan about 9 years
    Exactly. But I found no other method that could remove text-blur problem in Chrome. So, I've been using zoom for my website. Can't understand the downvotes though!
  • Brian McCall
    Brian McCall over 8 years
    not sure why the downvote. When I applied this to checkboxes this worked much better than transform: scale()
  • Naisheel Verdhan
    Naisheel Verdhan over 8 years
    For firefox, use transform: scale() works like charm without any blurriness. You'll have to work on browser detection and act accordingly for chrome/safari and firefox.
  • Kai Hartmann
    Kai Hartmann over 8 years
    -webkit-filter: blur(0); alone works for me. backface-visibility: hidden; blurs my element when I reset the scaling afterwards.
  • ericgrosse
    ericgrosse about 8 years
    Another issue is that zoom doesn't seem to work with the transition property, so it can't be used for CSS animations
  • David Blurton
    David Blurton almost 8 years
    There is no filter: scale according to developer.mozilla.org/en/docs/Web/CSS/filter
  • Sardtok
    Sardtok almost 8 years
    It should be blur according to the referenced URL in the answer.
  • Tom Roggero
    Tom Roggero over 7 years
    this is kinda funny for Chrome... if i set blur(0px); it doesnt fix it. but if i do blur(1px); and then press the arrow down key to blur(0px); it does look correct. Gone on page refresh / no matter what I write in the CSS
  • user1156544
    user1156544 over 7 years
    It works and fox the blur thing, but it also changes position of elements.
  • Naisheel Verdhan
    Naisheel Verdhan over 7 years
    @user1156544 : yes it does, that would anyway be happening even when you're doing transform: scale({scaleVal});, you will need to position your elements left/top accordingly which is an easy calculation based on {scaleVal}
  • ITWitch
    ITWitch over 7 years
    backface-visibility: hidden; sure worked in my case, in solving some weird blurry movement cause by opacity transition, that is. The weird movement is now gone, BUT it has made the texts in my div permanently blurred instead.
  • Serge Eremeev
    Serge Eremeev about 7 years
    As @ykadaru suggested, try adding perspective(1px) to your transform: code, this worked for me in Chrome while nothing else solved the problem
  • Dustin Poissant
    Dustin Poissant almost 7 years
    No firefox support for zoom
  • Gajus
    Gajus almost 7 years
    @TomRoggero This sounds less specific to the blur property value and more about when redraw of the layout is done. You could experiment forcing redraw of the element using JavaScript after some delay.
  • Quentin Engles
    Quentin Engles over 6 years
    I used even numbered dimensions, and the element is still blurry.
  • Marecky
    Marecky about 6 years
    Does not work on Chrome Version 65.0.3325.162 (Official Build) (64-bit) running in Ubuntu 17.10 with Gnome X11 session (Wayland off)
  • balu
    balu about 6 years
    For me, this actually makes it worse.
  • balu
    balu about 6 years
    Adding perspective(1px) actually made it worse for me :(
  • hugo der hungrige
    hugo der hungrige about 6 years
    That's the only approach that worked for me. The other approaches (backface-visibility, adding filters, perspective and good old translateZ) just made it worse. Try scaling to whole pixels. For example go from 14px to 16px using a scale factor of 1,1429 (16/14).
  • Leo
    Leo over 5 years
    This simply doesn't add anything to this post.
  • Diazole
    Diazole over 5 years
    Did you get anywhere with your bug report?
  • andyw
    andyw over 5 years
    afraid I don't even recall where I submitted the bug to. Did so though.
  • brandito
    brandito over 5 years
    In Chrome 72 the first two options cause the text to be blurry during & at the end of the transform
  • Dan
    Dan over 5 years
    Why would anyone downvote this? I don't get it... :( This is a completely valid issue in some versions of chrome, and it seems "will-change" in general is still pretty new and probably shouldn't be used. For more info see greensock.com/will-change
  • Iggy
    Iggy about 5 years
    IN my case backface-visibility: visible; helped to save the blurred text :)
  • raine
    raine about 5 years
    Had the same issue. Thanks for posting.
  • Sergiu
    Sergiu about 5 years
    For me this fixes the glitch (without this, the element moves 1px after animation is done, transform: perspective(1px) alone fix this!)
  • Tomek
    Tomek about 5 years
    Not supported by any version of FF! So you probably don't want to use it.
  • ykadaru
    ykadaru about 5 years
    @balu check my updated answer! get rid of the perspective(1px) property and see if it works better.
  • jpenna
    jpenna about 5 years
    This for me just removed the scale() transform result
  • Vector
    Vector almost 5 years
    I've been experiencing other bugs (like partially changed opacity for rgba values) caused by scale() and backface-visibility: hidden; fixed them--blurry text isn't the only weird thing that happens. I have only experienced these bugs in Chromium browsers.
  • Rob
    Rob almost 5 years
    I had the same issue with material-design-components rendering on Chrome 75. Removing the "will-changed" css style fixed it.
  • kwiat1990
    kwiat1990 almost 5 years
    This is what happened to my. I can't get rid of this blur effect. One solution which have worked is to set these properties: top: 0, bottom: 0, left: 0; right: 0; margin: auto but then the container will take the whole space it can (it must be width), so this doesn't work in case when the content should decide how big container will be.
  • CloudBranch
    CloudBranch over 4 years
    This is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.
  • A. Volg
    A. Volg over 4 years
    Worked for me without translateZ(0), changed just 1.05 to 1.048
  • some
    some over 4 years
    I'm using a transition with opacity and scale on a parent element. During the transition the text was blurry and when finished it jumped a few pixels. By adding backface-visibility: hidden; on the element that jumped, it was solved. Used chrome 77.0.3865.90 on Windows.
  • Chris Gutierrez
    Chris Gutierrez over 4 years
    I was running in to this exact same issue doing the exact same thing. I was centering a modal with translate3d(-50%, -50%, 0). In my case, I bumped up the values to -50.048% and it looks perfect.
  • Boltgolt
    Boltgolt over 4 years
    Note that zoom is not defined by any web standard and is not supported by firefox caniuse.com/#feat=css-zoom
  • Timothy003
    Timothy003 over 4 years
    Blurriness is expected when using translation, because the element can end up on a half pixel. There are now better alternatives for centering things: flexbox sample, grid sample
  • SJacks
    SJacks over 4 years
    The only browser I've tested which seems to have an issue with transform center is Chrome, everything else appears crystal clear. I looked back and this issue has been around for 7 years! Still there's plenty of ways to skin a cat and like you say it's not even required anymore.
  • Fareesh Vijayarangam
    Fareesh Vijayarangam over 4 years
    Confirmed in Chrome 79
  • Arthur
    Arthur about 4 years
    insane but it works; Chrome is the new IE apparently
  • Jakub Zawiślak
    Jakub Zawiślak about 4 years
    I have the opposite, adding will-change: transform; slightly fixes the issue
  • Jakub Zawiślak
    Jakub Zawiślak about 4 years
    It works for me and it is also marked as unused. I have also added will-change: transform; that fixes blurry of elements borders. Any other answers didn't worked for me.
  • akinuri
    akinuri about 4 years
    I'm using Bootstrap (4.4.1), Chrome (80.0.3987.132), Windows 10 (with view 125% scaled up) and I have blurry texts in dropdown menu. The menu is positioned using transform: translate3d(); and this seems to cause the problem. None of the suggested solutions worked for me. Except/kinda this one. This works only if I set it first to some positive value (e.g., blur(0.1px)) and then change to blur(0px). Since the element is dynamic, and also requires a dynamic (JS) solution, ... this sucks :\
  • jt3k
    jt3k about 4 years
    this is unbelievable, but filter: blur (-0.1px); helped me !!. how the hell does this work ??
  • Ilya Luzyanin
    Ilya Luzyanin about 4 years
    Worked for me on Chrome 80, unlike other fixes. Now it's only blurry during the transition animation, which is a different issue, I guess. Thanks!
  • King James Enejo
    King James Enejo about 4 years
    It is not advisable to use zoom property just yet. According to MDN, it is a Non-standard CSS property. Read more here: developer.mozilla.org/en-US/docs/Web/CSS/zoom
  • LuanLuanLuan
    LuanLuanLuan almost 4 years
    oooow lord! ir works! i guess table 'fix' de width in PX did not possible width with half-pixel...
  • Denis TRUFFAUT
    Denis TRUFFAUT over 3 years
    Yes, using width:0 and height:0, and animating with transition : width .15s, height.15s (instead of transform:scale(0) and transition:transform .15s) does the job, but you lose the transform origin (may be I can hack this by animating margin), and it is a little bit janky (I can see 2-3 intermediate frames)
  • Denis TRUFFAUT
    Denis TRUFFAUT over 3 years
    Using even numbers didn't help with the bluriness of the animation BUT it helped with my subpixel positionning, which was another problem I had when positionning items in an infinite scroll. Thanks for the tip !
  • alex
    alex over 3 years
    This fixed it for me on Chrome 86
  • Ian Wesley
    Ian Wesley over 3 years
    Now for me it starts blurry and goes to clear.
  • Balázs Varga
    Balázs Varga over 3 years
    You should use backface-visibility: hidden; AND transform: translateZ(0); . Z transform tells the engine to use 3D rendering. Until that, backface-visibility has no effect.
  • MrSegFaulty
    MrSegFaulty over 3 years
    This 'solved' the problem in Firefox 85 on Windows and improved, but not completely solved in Chrome 88... Also, sadly, you can't really use it freely.
  • Timothy003
    Timothy003 over 2 years
    @jt3k You're forcing Chrome to render in software, which rounds to the nearest pixel. In short: don't do that.
  • Jorge Fuentes González
    Jorge Fuentes González over 2 years
    You answered with exactly the same question code.
  • Mohammad Ghonchesefidi
    Mohammad Ghonchesefidi over 2 years
    Thanks worked great
  • Aaron Meese
    Aaron Meese almost 2 years
    Note that this won't work on span or any other inline elements.
  • Aaron Meese
    Aaron Meese almost 2 years
    This did not make a difference for me