Fix Pixelated Font Icons in Chrome on Windows
Firstly if you have not made the switch to font based icons, stop reading and check out this (awesome) free icon pack:
http://fortawesome.github.io/Font-Awesome/
So why use fonts instead of images?
1.) Any size, clean and crisp at any resolution.
2.) Small, font files are much smaller than a series of images, especially for those creating double sized images to support Retina displays.
3.) Supported by all legacy, and modern browsers, any platform.
Before you jump in, you should really check out IcoMoon by Keyamoon. I have never used a free web app of this quality before, the author has done a really good job.
Getting back on topic, if you read here on IcoMoon's blog: http://icomoon.io/#post/318 you will discover Chrome running under Windows has some real problems with font rendering.
Here are some samples from Chrome, IE and Firefox (all on windows)
Chrome [Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36]:
IE10 [Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)]:
FF20 [Mozilla/5.0 (Windows NT 6.2; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0]:
How do we fix this?
So the initial solution is to move SVG to the top:
@font-face
{
font-family: 'echovoice';
src: url('/fonts/echovoice.svg#echovoice') format('svg');
....
Why is this BAD?
"SVG fonts lack compression and therefore they are very large in size compared to other font formats"
Fine, lets use CSS to detect Chrome and force it to use SVG (from stackoverflow.com)
@font-face
{
font-family: 'echovoice';
src:url('/fonts/echovoice.eot');
src:url('/fonts/echovoice.eot?#iefix') format('embedded-opentype'),
url('/fonts/echovoice.woff') format('woff'),
url('/fonts/echovoice.ttf') format('truetype'),
url('/fonts/echovoice.svg#icomoon') format('svg');
font-weight: normal;
font-style: normal;
}
@media screen and (-webkit-min-device-pixel-ratio:0)
{
@font-face
{
font-family: 'echovoice';
src: url('/fonts/echovoice.svg#echovoice') format('svg');
}
}
Up until now all I have done is reiterate IcoMoon's blog post.. now for the reason I decided to write this post...
If you take a look at the network activity under Chrome you will see the following:
So it loads both the svg and woff, this isn't ideal at all.
My solution is to move the above CSS to a separate stylesheet (echovoice.css), now that noscript tags are legal inside the head
<noscript>
<link href='/fonts/echovoice.css' rel='stylesheet' type='text/css'>
</noscript>
This will allow users with js disabled to pull in the styles to load the fonts.
Then I added the following directly below the noscript tags in the head for our js users
<script type="text/javascript">
var b="<style>@font-face{font-family:'echovoice';src:";/win/.test(navigator.userAgent.toLowerCase())&&/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())||(b+="url('/fonts/echovoice.eot');src:url('/fonts/echovoice.eot?#iefix') format('embedded-opentype'),url('/fonts/echovoice.woff') format('woff'),url('/fonts/echovoice.ttf') format('truetype'),");b+="url('/fonts/echovoice.svg#icomoon') format('svg');font-weight:normal;font-style:normal}</style>";
document.write(b);
</script>
What this simply does is test for the combination of chrome and windows, if that combination is found then it will only write the svg path for src, otherwise it will write paths for all the font options.
Success, only the SVG file is downloaded in Chrome under Windows and no more fuzzy icons!
Related protips:
Written by Mike Olsen
Related protips
2 Responses
I found a better solution. You just need put the SVG before all other font types and the Chrome will automatic use it instead of Woff. Firefox will use Woff and IE will use EOT (and for avoid IE bugs it's a good idea put SVG after EOT);
https://gist.github.com/Gnuns/9749722
@font-face
{
font-family: 'echovoice';
src:url('/fonts/echovoice.eot');
src: url('/fonts/echovoice.eot?#iefix') format('embedded-opentype'),
url('/fonts/echovoice.svg#icomoon') format('svg'),
url('/fonts/echovoice.woff') format('woff'),
url('/fonts/echovoice.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
thanks @gnuns for the feedback, my only concern with doing that is (if I remember correctly) is safari will download both woff and svg now. The other issue is, svg fonts are much much bigger so doing this to all chrome browsers will increase load time and bandwidth, even if they are on a mac which renders the woff just fine.