Blurry text after using CSS transform: scale(); in Chrome
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.
Related videos on Youtube
Ryan O'Rourke
Updated on April 23, 2022Comments
-
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 over 11 yearsJust 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 about 11 yearsI don't see any blurring...i'm on Chrome v25/PC
-
raj_n about 11 yearsI've come across this problem earlier too, as Nolonar mentioned we'll have to wait for Google to fix it.
-
Bangkokian about 5 yearsNot a solution, but I have noticed that the issue only occurs for me when I use CSS optimizeLegibility.
-
Timothy003 over 4 yearsLink is broken.
-
dziku86 about 3 yearshtml5rocks.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 about 10 yearsThese 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 about 9 yearsIt can help but also introduces other issues, like white border lines being introduced sometimes
-
Naisheel Verdhan about 9 yearsExactly. 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 over 8 yearsnot sure why the downvote. When I applied this to checkboxes this worked much better than transform: scale()
-
Naisheel Verdhan over 8 yearsFor 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 over 8 years
-webkit-filter: blur(0);
alone works for me.backface-visibility: hidden;
blurs my element when I reset the scaling afterwards. -
ericgrosse about 8 yearsAnother issue is that zoom doesn't seem to work with the transition property, so it can't be used for CSS animations
-
David Blurton almost 8 yearsThere is no
filter: scale
according to developer.mozilla.org/en/docs/Web/CSS/filter -
Sardtok almost 8 yearsIt should be blur according to the referenced URL in the answer.
-
Tom Roggero over 7 yearsthis is kinda funny for Chrome... if i set
blur(0px);
it doesnt fix it. but if i doblur(1px);
and then press the arrow down key toblur(0px);
it does look correct. Gone on page refresh / no matter what I write in the CSS -
user1156544 over 7 yearsIt works and fox the blur thing, but it also changes position of elements.
-
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 elementsleft
/top
accordingly which is an easy calculation based on{scaleVal}
-
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 about 7 yearsAs @ykadaru suggested, try adding
perspective(1px)
to yourtransform:
code, this worked for me in Chrome while nothing else solved the problem -
Dustin Poissant almost 7 yearsNo firefox support for
zoom
-
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 over 6 yearsI used even numbered dimensions, and the element is still blurry.
-
Marecky about 6 yearsDoes 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 about 6 yearsFor me, this actually makes it worse.
-
balu about 6 yearsAdding
perspective(1px)
actually made it worse for me :( -
hugo der hungrige about 6 yearsThat'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 over 5 yearsThis simply doesn't add anything to this post.
-
Diazole over 5 yearsDid you get anywhere with your bug report?
-
andyw over 5 yearsafraid I don't even recall where I submitted the bug to. Did so though.
-
brandito over 5 yearsIn Chrome 72 the first two options cause the text to be blurry during & at the end of the transform
-
Dan over 5 yearsWhy 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 about 5 yearsIN my case backface-visibility: visible; helped to save the blurred text :)
-
raine about 5 yearsHad the same issue. Thanks for posting.
-
Sergiu about 5 yearsFor me this fixes the glitch (without this, the element moves 1px after animation is done, transform: perspective(1px) alone fix this!)
-
Tomek about 5 yearsNot supported by any version of FF! So you probably don't want to use it.
-
ykadaru about 5 years@balu check my updated answer! get rid of the
perspective(1px)
property and see if it works better. -
jpenna about 5 yearsThis for me just removed the
scale()
transform result -
Vector almost 5 yearsI've been experiencing other bugs (like partially changed opacity for rgba values) caused by
scale()
andbackface-visibility: hidden;
fixed them--blurry text isn't the only weird thing that happens. I have only experienced these bugs in Chromium browsers. -
Rob almost 5 yearsI had the same issue with material-design-components rendering on Chrome 75. Removing the "will-changed" css style fixed it.
-
kwiat1990 almost 5 yearsThis 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 over 4 yearsThis 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 over 4 yearsWorked for me without
translateZ(0)
, changed just1.05
to1.048
-
some over 4 yearsI'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 over 4 yearsI 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 over 4 yearsNote that
zoom
is not defined by any web standard and is not supported by firefox caniuse.com/#feat=css-zoom -
Timothy003 over 4 yearsBlurriness 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 over 4 yearsThe 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 over 4 yearsConfirmed in Chrome 79
-
Arthur about 4 yearsinsane but it works; Chrome is the new IE apparently
-
Jakub Zawiślak about 4 yearsI have the opposite, adding
will-change: transform;
slightly fixes the issue -
Jakub Zawiślak about 4 yearsIt 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 about 4 yearsI'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 toblur(0px)
. Since the element is dynamic, and also requires a dynamic (JS) solution, ... this sucks :\ -
jt3k about 4 yearsthis is unbelievable, but filter: blur (-0.1px); helped me !!. how the hell does this work ??
-
Ilya Luzyanin about 4 yearsWorked 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 about 4 yearsIt 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 almost 4 yearsoooow lord! ir works! i guess table 'fix' de width in PX did not possible width with half-pixel...
-
Denis TRUFFAUT over 3 yearsYes, 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 over 3 yearsUsing 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 over 3 yearsThis fixed it for me on Chrome 86
-
Ian Wesley over 3 yearsNow for me it starts blurry and goes to clear.
-
Balázs Varga over 3 yearsYou should use
backface-visibility: hidden;
ANDtransform: translateZ(0);
. Z transform tells the engine to use 3D rendering. Until that,backface-visibility
has no effect. -
MrSegFaulty over 3 yearsThis '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 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 over 2 yearsYou answered with exactly the same question code.
-
Mohammad Ghonchesefidi over 2 yearsThanks worked great
-
Aaron Meese almost 2 yearsNote that this won't work on
span
or any other inline elements. -
Aaron Meese almost 2 yearsThis did not make a difference for me