EOT usage technique

Just a quick note on EOT usage, Paul Irish has put together a nice hack for working around some IE EOT loading problems:

http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/

Ideally, using a combination of downloadable font formats would work using format hints, IE would load the EOT font and other browsers the TrueType font:

  @font-face {
    font-family: FishyFont;
    src: url(fishy.ttf) format("truetype"), url(fishy.eot) format("embedded-opentype");
  }
  
But IE never implemented format hints so this doesn't work.  One simple way to workaround this is to define different rules for different formats:

  @font-face {
    font-family: FishyFont;
    src: url(fishy.eot); /* for IE */
  }
  
  @font-face {
    font-family: FishyFont;
    src: url(fishy.ttf) format("truetype"); /* for non-IE */
  }
  
Or you can also use IE conditional comments to define IE-specific rules, as Jon Tan proposed:

http://jontangerine.com/log/2008/10/font-face-in-ie-making-web-fonts-work

  <style type="text/css" media="screen">
  
  @font-face {
    font-family: FishyFont;
    src: url(fishy.ttf) format("truetype"); /* for non-IE */
  }
  
  </style>
  
  <!--[if IE]>
  
  <style type="text/css" media="screen">
  
  @font-face {
    font-family: FishyFont;
    src: url(fishy.eot); /* for IE */
  }
  
  </style>
  
  <![endif]-->
  
Both of these suffer from one problem, IE always tries to pull a font with a URL of *anything* that's between the url left-paren and the last right paren on the line:

  @font-face {
    font-family: HavingFunWithIE;
    src: url(gentium.ttf) my-lord("you have smelly underwear");
  }
  
Look in your server logs and you'll find this

"GET /gentium.ttf)%20my-lord(%22you%20have%20smelly%20underwear%22 HTTP/1.1" 404

Not terrible but it eats up available connections and will slow the page load.  You could always use some server rewrite rules to map these funky URLs to EOT versions of the appropriate fonts but that's a nasty, evil hack (must try this immediately...).

Paul Irish's solution is to use several descriptors in one @font-face to work around the problem:

@font-face {
  font-family: FishyFont;
  src: url(fishy.eot); /* for IE */
  src: local(FishyFont), url(fishy.ttf) format("truetype"); /* for non-IE */
}

This works around the problem because using local() causes IE to ignore the line defining the TrueType font and pull down *only* EOT data.

For large sites, a nice technique is to put multiple font definitions into a single site-wide font definitions file; the file will be loaded the first time a site is hit and pulled from the cache for subsequent pages within the same site:

  @import url("fonts.css");
  
Pages only use the fonts they need, otherwise fonts aren't downloaded in non-IE browsers.  However, the downside of this approach is that IE currently downloads *all* of the fonts included, regardless of whether they're used on the page or not.  If you define a family with regular, bold, italic and bold italic face but only use the regular face on a given page, IE will still pull down all four faces.  For sites that want to use this technique, the workaround is to use browser-specific stylesheet rules (*sigh*).

Note on testing: clearing the browser cache in IE8 doesn't seem to clear out downloaded fonts.  You need to hit [F12], bring up the developer's menu and choose Cache > Always Refresh From Server to get an accurate picture of what's going on.

Cheers,

John

Received on Thursday, 10 September 2009 07:29:27 UTC