i wanted to jump on the icon font train, but was quickly put off by the renderer. When an icon is sitting inside a div that has either percentage width or is automatically centered the icon can be aligned to a half pixel causing it to be rendered blurry.
I was in contact with Icomoon support who intoduced me to a bug that said it is Chrome specific. (https://bugs.chromium.org/p/chromium/issues/detail?id=426333) unfortunately I was able to reproduce the issue in all of the major browsers.
The recommendation I got was to avoid auto margin and to use only float left which in today's world isn't really possible. And even if I do that i'd still clash with precentage widths.
Question
Is there any way to preven't the blur from occuring? I guess using inline-svgs would be an option right? But that kinda beats the whole purpose of the Icon Font. Or having a script that rounds everything up to whole pixels but that sounds extreme as well.
Steps to reproduce the issue
I have created a 24px set of icon on Icomoon, downloaded the set which comes with a demo.html. Then I just to the main wrapper of the demo, and gave it a fix width and margin 0 auto. Then by resizing the browser width I was able to make the icons blur or be crisp..
Chrome
Blurry:
Crisp:
Firefox
Blurry:
Crisp:
Opera
Blurry:
Crisp:
Edge
Blurry:
Crisp:
Internet Explorer
Blurry:
Crisp:
If someone can provide evidence that this is what's actually happening in the browser implementations that would be ideal, but this answer is based on your even/odd pixel values you mentioned in the question and is what I believe to be the most likely cause.
On a basic level, icon fonts are vectors. This allows the icons to scale regardless of font size and not become blurry. Blurriness can however occur when the edges of the vectors do not line up with the edges of pixels.
To steal from the Font Awesome Icon Design Tips Guide, you can see two demonstrations below. The top image is a vector with a bunch of 1px
wide lines, spaced 1px
apart, but they're offset by 0.5px
. When rendered as pixels without being zoomed in, this causes them to become blurred as the pixel must take 50% of the line colour, and 50% of the background colour.
Vector edges that don't line up with the pixel edges. (The blue representing the 0.5px offset from the pixel edge).
On the other hand, the image below has the vectors lined up, so that either edge of the lines/bars, lines up with the edges of the pixels. Therefore when rendering at a pixel level, no pixels have to merge the background and line colours.
Correctly aligned vectors
To see more examples to explain this in more detail, I'd recommend reading the full guide which also explains crisp diagonal edges too.
Browsers now have to deal with high DPI/retina screens, which make it really easy to have "centered" text because you have 2 actual pixels per CSS px
width; therefore you can draw crisp lines every 0.5px
.
Judging by your images, you're using a regular DPI screen to view the fonts, and therefore when the browser is forced to render the icon at a 0.5px
value, the edge of the vector lies in the middle of a pixel, rather than half way, meaning that pixel has to take 50% of the background colour, and 50% of the icon colour, causing the blurred edge.
As for a solution, I sadly don't have a lower res monitor on hand to test. Your aim is to make the edge of the icon render on the edge of the pixel boundary which will require some fiddling, but here are some things you could try:
display: inline-block
instead of the default display: inline
that text tends to have. (Unlikely to work, but it might).div
just larger than the icon size that can then be centered.div
method, try the difference with left aligning or center aligning the text.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With