RE: EOT usage technique

Thursday, September 10, 2009 John Daggett <jdaggett@mozilla.com>:

>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/
>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.

John,

There were some things about Paul Irish's workaround that, frankly, I found less than appealing. And during testing, a real deal-killer cropped up, at least for me:

 1) It works fine in Firefox 3.5, Chrome w/webfonts-enabled, Internet Explorer, and Safari. It doesn't work in (brace yourself for a shock, now) Opera 10! Opera's debugger declares "fishy.eot", or any EOT, as an "invalid src property" and, unlike the other browsers, Opera does not simply pass it by and parse the next, presumably valid, rule. Instead it disregards the contents of the entire parent @font-face rule that contains the offending rule. It just throws the whole thing away. So, Paul's syntax works in all browsers except Opera. How come? Who knows? Hah!
So, if we're going to accommodate Opera, we're back to a two-rule solution.
But there are other issues, anyway...
 2) I didn't like the local descriptor being a *must*. If you have no reason to use it because the chances of the font being installed are nil, using local is strangely conspicuous. And making up a dummy font name just to get the syntax I find clunky. But in either case, it's not very evident or obvious that it has a dual purpose as a workaround. Confusion in the making, it seems to me. Better to leave local() to its intended, single purpose.
 3) Backwards compatibility issues are best addressed, I think, with CSS that's separate and apart from the compliant, forward compatible stuff - in the spirit of Jon Tan's approach with conditional comments. Co-mingling the src calls within the same @font-face rule just feels, intuitively, wrong to me.
In other words, I didn't see the following as being ideal, at all, even if Opera was OK with it:

>Ideally, using a combination of downloadable font formats would work using format hints
  >@font-face {
    >font-family: FishyFont;
    >src: url(fishy.ttf) format("truetype"), url(fishy.eot) format("embedded-opentype");
  >}

However, as you point out, the following suffers from IE attempting to "double dip", and getting a 404 on dip two:
    
    >@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 */
    >}

>Not terrible but it eats up available connections and will slow the page load

After "Fiddler-ing" around with it for awhile, I came up with something that makes Opera happy, keeps the @font-face rules separate without relying on conditional comments, avoids the additional HTTP request by IE, and leaves local() as an option, not a requirement:

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


Another plus is that, as a workaround, it's self-labeling: substitute your text of choice for "no-IE-404". "Do-Not-Remove" will do nicely.
It'll probably validate, too, but I haven't checked.
I've tested this out pretty thoroughly on IE8 but not, as yet, on IE6 and 7 but will do so soon.
If there's any problems with it, I'll be posting it on my blog tomorrow or the next day for comment.

Regards,

rich

Received on Monday, 14 September 2009 05:57:07 UTC