Thursday, September 3, 2009

@font-face we are already doing wrong

Update - Now We Do Right

Thanks everybody for your tests and contributions. For those interested about why we were doing wrong please read both post and comments but for those just interested about the best way so far to serve correctly one or more font-face, this is the hack:

@font-face {
// define the font name to use later as font-family
font-family: "uni05_53";
// define the font for IE which totally ignores local() directive
src: url(../font/uni05/uni05_53.eot);
// use local to let IE jump this line and
// redefine the src for this font in order to let
// other clever browser download *only* this font rather than 2
src: local("uni05_53"), url(../font/uni05/uni05_53.ttf) format("truetype");

You can test directly this technique in my HTML5 Prime Directives Test Page


  • Paul Irish for its Bulletproof @font-face syntax

  • Mikuso, comments, for his suggestions about server configurations, instantly followed by Weston Ruter for its excellent article Efficiently Serving Custom Web Fonts

  • last, but not least, Scott Kimler, for his Better @font-face Syntax and his patience, testing directly inside a trace log, rather than trust 100% Fiddler or Firebug - P.S. my hat is off for that page, unfortunatly you have trolls problems as well, reading the first comment from somebody that got -1% of what you have done!
Links, snippets, tests, we have got everything we need to understand why font-face CSS plus file serving has been generally misunderstood and how we should do correctly, trolls included (the problem is not the browser).

Good Stuff!
Just last quick info for Scott Kimler, IE simply lacks "local" directive support, and this is the reason it ignores the second call.
If we put local(fontName), url(fontName.eot) it will not load the eot, neither the ttf - local is the key for this trick, but we'll have problems the day IE will understand local, unless the first src will not considered synchronous.
Hopefully, that day IE will support ttf since windows does already without problems.

Few weeks with new browsers and @font-face support that suddenly everybody started to suggest the "cross browser way" to include them ... which is 90% of cases apparently wrong.

The Wrong Way

/* IE first */
@font-face {
font-family: nomeDelFont;
src: url( /nomeDelFont.eot );

/* Firefox 3.5/Safari/Opera 10 */
/* but IE will download in any case */
@font-face {
font-family: nomeDelFont ;
src: url( nomeDelFont.ttf );

almost the equivalent showed here, via Ajaxian, and Edit ...

What Is Exactly Wrong

It does not matter if we use conditional comments, it does not matter if we put the right font for Internet Explorer before the other one (tricky, since IE does not overwrite the rule just because it does not understand the truetype format).

Our "favorite" browser, and others as well in some case, will always request the truetype as well, and being fonts not that lightweight, our page response could sensibly increase.

HTML5 Prime Directives

Inspired by RoboCop, I have created a simple test page that does not suffer the problem described before.
What we have there is an extremely compact and valid HTML5 page which size is up to 140Kb, and almost 67Kb just for the font.

Plus, as I've said, If we use common suggested snippets Internet Explorer will download in any case the non IE font, try yourself!

First Suggestions To Try To Solve The Problem

  1. never forget to specify the format, format("truetype"), which is apparently able to let IE misunderstand correctly the url and the result is a Error 404, still better than 70Kb to download

  2. moreover, use whatever strategy you know to avoid non IE file serving for IE as well (use Fiddler to monitor the network)

  3. try to create gzipped or deflated version of each font, possibly not runtime, and serve them via proper headers (69Kb down to 22Kb, as example, with 7Zip deflate)

  4. please tell us how you avoided IE wrong font download without using an horrible JavaScript document.write as I did in my little test page

Thanks, and I hope you agree about Prime Directives :D

No comments:

Post a Comment