Chrome Font appears Blurry
Asked Answered
G

26

66

It's doing my eyes in!

looks fine in IE and Firefox

enter image description here

Chrome(Above)

Running version 39 of chrome, only appears blurry in a modal box, does not make any difference if I change the font family.

This is the CSS (for label "Start") the browser renders the following

box-sizing: border-box;
color: rgb(85, 85, 85);
cursor: default;
display: block;
float: left;
font-family: sans-serif;
font-size: 12px;
font-weight: 600;
height: 24px;
line-height: 17.142858505249px;
margin-bottom: 0px;
margin-top: 0px;
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
padding-top: 7px;
position: relative;
text-align: right;
visibility: visible;
width: 89.65625px;

Is it the browser or CSS?

--UPDATE---

Ok looks like its this CSS

.md-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    width: 50%;
    max-width: 630px;
    min-width: 320px;
    height: auto !important;
    z-index: 2000;
    visibility: hidden;
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    backface-visibility: hidden;
    -webkit-transform: translateX(-50%) translateY(-50%); <--- This line
    -moz-transform: translateX(-50%) translateY(-50%);
    -ms-transform: translateX(-50%) translateY(-50%);
    transform: translateX(-50%) translateY(-50%);
}

However if I take it out my modal no longer centres?

Gredel answered 9/12, 2014 at 17:31 Comment(11)
Are there any CSS transforms on any of the parent elements? It looks like it's being positioned on a decimal of a pixel.Guardsman
Can you paste your markup into a JSFiddle or something, to see if it replicates there? The styles alone do not allow me to reproduce thisOft
You could try something like -webkit-font-smoothing: none;Lampe
@Guardsman Hey, not being a CSS expert what am I am looking for?Gredel
Hey updated the main postGredel
try with translate3dJerlenejermain
Do you also have this problem in other browsers?Barrio
@D-W, any luck with my answer?Markhor
Hey, sorry it made no difference, Im now looking to use another modal control instead, appreciate the response thoGredel
I use matrix normalization after layout : https://mcmap.net/q/144668/-chrome-font-appears-blurryGuipure
@Gredel change the position: relative; to position: unset;Tailback
C
46

I fixed this issue by subtracting 0.5px from the value of the Y-axis. So instead of doing:

transform: translateX(-50%) translateY(-50%);

I did this:

transform: translateX(-50%) translateY(calc(-50% - .5px));

This solved it for me and I find this a cleaner solution then fiddling around with the percentage or using Javascript.

Caundra answered 5/3, 2017 at 20:44 Comment(8)
It did the trick for me too. Have tried using perspective(), with translateY(50.1%), using scale(1.0, 1.0) and others solutions.Prolocutor
most clutch answer I've found in some time :)Ensnare
How can you be sure it would be fixed accros all devices ?Narcho
This didn't fix the issue for me (Chrome 75).Yarborough
- .4px is sharper :)Arleta
Wow! Probably more hacky than Miguels very good answer but this is so much more reliable to me that it's very worth it until browsers start implementing their own fixes for thisPhung
Stuck on hours and This worked for me. Thanks a lot :)Secondrate
Not sure why this has so many upvotes, this will just fix it if the element height happens to be an odd number of pixels (so -50% is not an integer). If it happens to be an even number of pixels, it will do the exact opposite. So the result will vary depending on the size of the browser window.Millwright
C
37

I experienced the same issue on chrome after applying translate transform to one of my elements. It seems to be a bug on chrome. The only thing that worked for me was this:

#the_element_that_you_applied_translate_to {
  -webkit-filter: blur(0.000001px);
}

An Other solution can be turning smooth font rendering on:

#the_element_that_you_applied_translate_to {
  -webkit-font-smoothing: antialiased;
}
Clamp answered 12/3, 2016 at 7:40 Comment(4)
Thank you * 100000000. I've been facing this problem for a long time with no good solution.Trichloromethane
excellent solution with blur .. it was only thing that really fix this. ...but from yesterday it seems like this doesn't working anymore. Problem is only with translateY() this is what causes blurry content. I found that content is blurred only if height of an element is an odd number (225px = blured, 224px = sharp as it should be ). shame that developers can't fix this for years!!! At least chrome fully support flex, if your HTML structure allows parent > child(centerend) and you don´t care about IE try this: philipwalton.github.io/solved-by-flexbox/demos/…Lederman
I agreed with @nomak22 explanation.You can check it by changing line-height of the text.Dian
Does not work at all at the time of this comment. Chrome on Win10. -webkit-font-smoothing has absolutely no effect whatever the value is. And the blur filter just blurs things as it should, while I thought we were trying to remove the blurriness?Doordie
M
34

This fiddle tests out a few different solutions from:

Test Output

CSS Output

Fix 0

-webkit-transform: translateZ(0);
transform: translateZ(0);

Fix 3

-webkit-transform: translate3d(0,0,0) !important;
transform: translate3d(0,0,0) !important;
Markhor answered 13/12, 2014 at 23:1 Comment(8)
Wow ... is there a reason as to why this fixes it. Or is that a feature by design.Inspectorate
I'm not clear how this fixes it, your examples are completely overriding the transform he wants. transform: translateZ(0) is the last rule applied so the X/Y translations are ignored. This fixes the blurring because the X/Y transforms are the source of the problem. For those trying to center, those x/y transforms must remain.Directional
This is not a fix if it's exactly translate(-50%, -50%) (+ no blurry text) what one wants to achieveMultivocal
we need a real fix, is this something for google to solve? or is this simple "impossible to fix if someone wants to use transforms" ?Guipure
I think this answer is out of date. I no longer see this issue on the version of Chrome I am running. The issue doesn't present itself in the fiddle above.Markhor
check this transform matrix normalization https://mcmap.net/q/144668/-chrome-font-appears-blurryGuipure
In my case I moved a sidebar using ` transform: translateX(-18.75rem);. Changing it to use px` instead: transform: translateX(-300px), no blur anymore.Carbolize
If you want to center while applying the fix: transform: translate3d(-50%, -50%, 0) does the trick :)Vaticination
G
15

The only correct way to solve this:

This problem arises from the fact of using % values to align the divs using css transforms. This results in decimals subpixel values, which your screen cannot render correctly. The solution is to normalize the resulting transformation matrix.

Might work better for fixed divs that don´t do transforming animation. But if you do animate you could use a after end callback to this function to correct the final state.

enter image description here

So: matrix (1,0,0,1,-375,-451.5) would become matrix (1,0,0,1,-375,-451)

I call this method before the .show() of jquery... Or maybe just once in the application ( depends on your case) , you might need to also call this on the resize event etc..

function roundCssTransformMatrix(element){
        var el = document.getElementById(element);
        el.style.transform=""; //resets the redifined matrix to allow recalculation, the original style should be defined in the class not inline.
        var mx = window.getComputedStyle(el, null); //gets the current computed style
        mx = mx.getPropertyValue("-webkit-transform") ||
             mx.getPropertyValue("-moz-transform") ||
             mx.getPropertyValue("-ms-transform") ||
             mx.getPropertyValue("-o-transform") ||
             mx.getPropertyValue("transform") || false;
        var values = mx.replace(/ |\(|\)|matrix/g,"").split(",");
        for(var v in values) { values[v]=v>4?Math.ceil(values[v]):values[v]; }

        $("#"+element).css({transform:"matrix("+values.join()+")"});

}

and call it

roundCssTransformMatrix("MyElementDivId");
$("#MyElementDivId").show();

Beautiful isn't it?

If you need to update on resize you could do it with:

$( window ).resize(function() {
  roundCssTransformMatrix("MyElementDivId");  
});

For this to work, all the parent must "be aligned / normalized" because if you by instance have the body with x=10.1px left, and the child is 10px .. the issue wont disapear because of the parent having residual decimals on their matrix So you must apply this function to the each element that is a parent and uses transform.

You can see this live script here: https://jsbin.com/fobana/edit?html,css,js,output

Guipure answered 15/2, 2017 at 18:3 Comment(1)
I was hoping for a css only solution, but this will do. I can't use any of the other suggestions on here as I'm using this css for multiple elements on the page. Some but not all elements have a round number when giving a -50% offset. So setting it to calc(-50% - .5px) would fix some elements, but break others.Singultus
G
10

Thanks for the CSS example. It seems translateX(50%) and translateY(50%) are calculating a pixel value with a decimal place (eg, 0.5px) which causes subpixel rendering.

There are many fixes for this but if you want to retain the quality of the text, your best solution right now is to use -webkit-font-smoothing: subpixel-antialiased; on .md-modal to force the render state for webkit browsers like Chrome and Safari.

Guardsman answered 11/12, 2014 at 10:46 Comment(5)
Hey thanks for the reply, I added that line, but no affect im afraidGredel
@Gredel have you found a solution yet? Do you have a Codepen or jsFiddle we can look at?Lenticular
I Math.round() 'ed the translateX(x) value for my code and the rendering is now smooth. Thanks.Larsen
@mak - can you provide some more detail on exactly how you implemented your solution using Math.round() ?Underling
I upvote this answer not because the solution worked for me, but because the first paragraph make me clear about what the cause of this issue. ThanksChingchinghai
L
5

I ended up fixing this by removing these lines:

-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
Longevous answered 28/8, 2016 at 9:43 Comment(0)
M
5

It took me a while to find a solution that I wouldn't bother using, so I'll post it here.

The problem for me was that the child div had width and height properties with a combination that caused the problem.

As I changed the height for another value, it just worked!

This probably has to do with the other answers, but I didn't want to use any JS or change the transform property to fix it.

Here is a live example: JSFIDDLE

Marco answered 10/8, 2017 at 20:19 Comment(1)
I am confused as to how this works.. but thanks for sharing. I will try this.Erose
L
3

If you want to center something, better use flexbox. It will help you position without having blurred text.

Add this to parent div of that element you want to center:

display: flex;
justify-content: center;
align-items: center;

Hope this helps.

Longshoreman answered 9/10, 2019 at 8:34 Comment(0)
A
2

Seems Chrome 78 still has this bug https://bugs.chromium.org/p/chromium/issues/detail?id=521364.

Building upon previous answers, I found the CSS below gave me the sharpest display on a translated modal:

transform: translate(calc(-50% - .4px), calc(-50% - .4px));

EDIT: For IE11 compatibility:

transform: translateX(-50%) translateX(-0.4px) translateY(-50%) translateY(-0.4px);
Arleta answered 11/11, 2019 at 17:8 Comment(0)
A
2

I know this is an old issue but since i stumbled across it in 2022 I thought I just tell someone who needs this how I solved it in my situation:

I had a modal with a textarea in it and in Chrome it was displayed blurry, but only when the textarea was overflowing. My modal - NOT the textarea itself - had overflow: hidden; so I just removed that.

enter image description hereenter image description here

Adversity answered 20/8, 2022 at 10:32 Comment(1)
what if you need the overflow though?Stratosphere
H
1

For modal boxes, this css will help:

-webkit-transform: translate3d(-50%, -51%, 0);
-moz-transform: translate3d(-50%, -51%, 0);
transform: translate3d(-50%, -51%, 0);

Instead of placing Y axis at 50%, make it 51%. This helps in my cse. If you have a different positioning, play around, but usually 1% up/down fixes blurry content.

Handoff answered 5/2, 2016 at 15:12 Comment(0)
C
1

TLDR

I faced this problem a few days ago. I almost went crazy trying to sharpen the fonts in Chrome. I have read all posts in this thread and in all other posts regarding sharpening fonts in Chrome. Even the message "The only correct way to solve this" did not help in my case. What helped?

It is worth mentioning that the problem occurred in the following div:

position: sticky;
left: 16%;

And the 'sticky' attribute turned out to be the biggest problem. For sticky elements, we set the position as for 'absolute' elements - using attributes the 'left', 'top' etc. And here is the problem: with not integer values ​​of the 'left' the font is rendered dramatically blurry, with integers it is much better.

What is the solution?

position: sticky;    
left: 0;
margin-left: 16%;

And that's all. Chrome will handle the percentage 'margin' and the fonts will look sharp.

Cholent answered 5/2, 2020 at 9:58 Comment(0)
R
0

Adding a CSS transition to the parent element of the parent element of my blurry element (which was using transformX which was causing blurriness) actually cancelled out the offending blurriness.

Rysler answered 16/9, 2016 at 12:6 Comment(0)
B
0

The similar issue happened for me.

I tried with all the suggested methods none worked fine. However,finally I resolved it. As there is an issue with google chrome having font-weight:600 or more. Try changing the font-family to font-family:"Webly Sleek SemiBold","Helvetica";

The font-weight property will work fine for it.

Blur_Font

Without_Blur

Between answered 13/11, 2018 at 14:57 Comment(0)
P
0

Another cause may be that you are not providing the needed font weights that you are utilizing.

For example, if you want to use both Lato or Roboto you want to include more than just the standard weight. This example applies if you are using Google Font API:

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,900|Roboto:500,700">

Note: Lato is available in 100, 300, 400, 700, and 900 font-weight, but I had to specify 900 for my 700 text to become crisp...not sure why.

Propertius answered 8/12, 2018 at 1:56 Comment(0)
B
0

For now, I found only one good solution:

transform: translate(-50%, -50.1%)

0.1% - in general user can't see this

Hope chrome will fix it - the bug exists since 2014))))

Behlke answered 15/5, 2019 at 6:22 Comment(0)
N
0

If you do not want implementing any special js or custom solution and the only what you want to achieve is center your div, and the width and height does not have fixed size, you can simply use this:

position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;

If one of sizes is fixed, you can try this approach:

position: absolute;
left: 50%;
translate: transformX(-50%);
top: 0;
bottom: 0;
margin: auto;

It fixes the problem with blurred font in chrome.

Neural answered 29/8, 2019 at 17:7 Comment(0)
C
0

You can solve this issue by putting:

    transform: inherit;
Christoperchristoph answered 14/11, 2019 at 10:43 Comment(0)
C
0

The best way I've found to resolve this issue which appears to only be an issue in Chrome and only on specific screen sizes, is to replace all transform:translate(-50%,50%) definitions with alternate solutions. Using any other solution may solve it on your screen, but not on another.

Transform definitions are usually used to center elements. Rather than using a transform definition, find another way to center your element, problem will be solved. In our case, we had a fixed div we wanted centered, with a max-width of 1800px and bottom set to 0px;

#cntr{position:fixed;left:50%;bottom:0;width:100%;max-width:1800px;transform:translateX(-50%);-ms-transform:translateX(-50%);-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-o-transform:translateX(-50%);text-align:center;}

Lot of definitions in there to cover all browsers. Changed to this to resolve it :

#cntr{position:fixed;left:0;right:0;margin:auto;bottom:0;width:100%;max-width:1800px;text-align:center;}

A lot less code, cleaner, faster, and worked 100%, without needing to edit any HTML.

Definitions that now center the fixed pos div are: left:0;right:0;margin:auto;

No translate required, no decimal point placed divs.

Chirrup answered 19/1, 2020 at 13:17 Comment(0)
B
0

For those still trying to find a solution to this, setting background fixed it for me for some reason.

background: #fff;
Backbencher answered 11/2, 2020 at 21:1 Comment(0)
V
0

I found that applying the translate3d(0, 0, 0) fix as JSuar suggested worked in Chrome but not Safari.

The one thing that did work across browsers was to give the element I was centring (using transform: translate(50%, -50%)) an even pixel width — changing the width from 425px to 426px made the text sharp again.

Villanelle answered 9/3, 2020 at 15:15 Comment(0)
B
0

The issue often happens with position: fixed; and transform: translate(...) when the width and height of the element are not a round even number.

One of the solutions is to round up the numbers programmatically. Example:

function roundToEven(x) {
  const rounded = Math.round(x)
  return rounded % 2 ? rounded + 1 : rounded
}
const element = document.getElementById('element-id')
const rect = element.getBoundingClientRect()
element.style.width = roundToEven(rect.width) + 'px'
element.style.height = roundToEven(rect.height) + 'px'
Besought answered 17/9, 2020 at 1:23 Comment(0)
A
0

You should choose your font with corresponding font weight which you want if you want thin, regular and bold text. You should choose font with weight 100 | 400 | 700 example: like below

Font weight is not only number. File should be available in server or directory. Each font weight is separate file.

If you force to change regular font into bold without resource, it showing with blurry. I hope you get it.

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100;400;700&display=swap');
Adamski answered 12/10, 2020 at 15:18 Comment(1)
Thanks, this was exactly my problem!Timoshenko
S
0

Just in case anyone is having this issue using the Roboto font from Google. My text was looking sort of blurry. I noticed that I wasn't importing the correct font-weight from Google. I needed 700 but wasn't including it.

https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap

vs

https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap

Sugarplum answered 5/5, 2022 at 22:38 Comment(0)
V
0

current fix for me: apply flexbox over your modal that needs to be centered. Make sure to span the height 100% of your view. You won't have to worry about the translate transform that will affect the subpixel value.

<div className="d-flex justify-content-center align-items-center h-100">
        ...
</div>
Vanish answered 5/4 at 17:59 Comment(0)
G
-1

I had this issue with my site as well, using a similar setup.

The issue appears because of a 0.5px difference.
An easy fix is to change the top property from 50% to calc(50% - .5px)

Griffiths answered 9/5, 2020 at 13:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.