Chrome Font appears Blurry

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.


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;
}

This fiddle tests out a few different solutions from:

  • CSS transition effect makes image blurry / moves image 1px, in Chrome?
  • WebKit: Blurry text with css scale + translate3d
  • http://www.useragentman.com/blog/2014/05/04/fixing-typography-inside-of-2-d-css-transforms/

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;

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


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.