@font-face for obscure Linux Browsers

UPDATE 2/3/2011: A new @font-face syntax has been released into the wild today: The Fontspring @font-face Syntax. This simple syntax looks like this:

@font-face { 
    font-family: 'MyFontFamily';
    src: url('myfont-webfont.eot#') format('embedded-opentype'),
        url('myfont-webfont.woff') format('woff'),
        url('myfont-webfont.ttf')  format('truetype'),
        url('myfont-webfont.svg#svgFontName') format('svg');
    }

I've checked this syntax in Konqueror 4.6 (KHTML) and gtk-webkit, as well as Opera 11 on Linux. Each browser displays the @font-face font correctly. Further testing is needed in some various browsers (including different versions of IE) to determine if everything is working perfectly and how well the syntax performs.

Back to the original article...

@font-face is an increasingly popular method of delivering custom fonts to display online. The syntax for using @font-face in a CSS file is pretty straightforward, but there are a number of cross-browser issues that complicate the matter. I'm going to describe the best syntax I've found that supports the largest number of browsers, including a couple Linux browsers that don't seem to support other syntaxes (is that a word?) that I've found online.

"Obscure"?

I didn't check just now, but I'm sure Firefox is the most popular Linux browser. There are, however, a number of people in the Linux community who harbor a dissatisfaction with Firefox and use an alternative browser. So, while the browsers described here are not widely used overall, they are pretty well-known among Linux users. The browsers are:

  • Konqueror, the KDE web browser. Konqueror uses the KHTML rendering engine, which (back in the day) served as the basis for the now-popular Webkit engine.
  • Epiphany and Midori are Webkit browsers. They both use the new GTK port of Webkit to render pages. While Webkit-GTK is very similar to the Webkit engines that power Safari and Chrome, there are a few minor differences. One of the differences is the treatment of @font-face syntax.

The Basis:

I originally started from Paul Irish's Bulletproof @font-face syntax here: http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/ and modified it a fair amount. That article is good reading and my intent is not to repeat it here. I also don't intend to be speaking with any authority on this subject, I'm just sharing what works for me. Anyway, read that article. A fair amount of what I'm writing is under the assumption you've read it.

Here's the Bulletproof syntax by Paul Irish (happy face and all):

@font-face {
    font-family: 'Graublau Web';
    src: url('GraublauWeb.eot'); /* for IE */
    src: local('☺'),
        url("GraublauWeb.woff") format("woff"),
        url("GraublauWeb.otf") format("opentype"),
        url("GraublauWeb.svg#grablau") format("svg"); /* these are for other browsers */
    }

My process - Issues and Resolution:

  • In my testing, it seems that GTK-webkit chokes on "local" and doesn't read the rest of the final "src" line above. Therefore, @font-face doesn't work. To resolve this, I moved "local" to a new "src" line. This makes IE choke (that is, the custom font does not display), but I'll take care of it later:

    src: url (...the eot filesrc: local('☺');
    src: url(...lots of stuff
    
  • Then I found that no matter where the "local" declaration is, Konqueror chokes. So I just got rid of it. IE still chokes.

  • To fix IE, I use a conditional comment to include the IE declaration separately:

    <!--[if IE]>
        @font-face {
            font-family: 'Graublau Web';
            src: url('GraublauWeb.eot');
        }
    <![endif]-->
    

    I actually just put this in a separate IE stylesheet. This isn't a problem for me since I almost always use a specific IE stylesheet. My normal stylesheet contains:

    @font-face {
        font-family: 'Graublau Web';
        src: url("GraublauWeb.woff") format("woff"),
            url("GraublauWeb.otf") format("opentype"),
            url("GraublauWeb.svg#grablau") format("svg");
        }
    

Browser Support:

I tested this in:

  • Firefox 3.6 (Linux)
  • Opera 10.5 (Linux)
  • Midori, using WebkitGtk+ 1.1.22 (fixed!) (remember, this browser uses the exact same Webkit engine as Epiphany, Uzbl, Jumanji, surf, vimprobable, etc., etc.)
  • Konqueror 4.4.2 (fixed!)
  • IE6, 7, 8
  • Google Chrome (Windows)

All these browsers display the @font-face font using my syntax above.

IE Gotcha's:

  • Not using a separate IE stylesheet? You won't like this solution, sorry. It requires double declarations.
  • Using the syntax I just described, IE will get a 404 "not found" message as it attempts to download a file that doesn't exist. See Paul Irish's post for more about this issue. See below for the workaround.
  • Microsoft has expressed support for the WOFF format. This is good in the long-term but in the short-term I wonder if it could create more problems with the release of IE9 and the need to support older versions of IE as well. An alternative syntax may be needed to deliver the WOFF font to IE9 and the EOT to earlier versions of IE. Gosh, I hope not.

IE 404 problem:

As I mentioned above, IE gets a 404 as it requests the WOFF font (actually, it requests a really long string that's not even a real address... Paul Irish's post describes this in more detail). The Mo' Bulletproofer syntax by Richard Fink (mentioned below) prevents this so my current syntax is as follows:

<!--[if IE]>
<style>
@font-face { /* I actually put this in my ie.css file */
    font-family: 'Graublau Web';
    src: url('GraublauWeb.eot');
    }
</style>
<![endif]-->
<style>
@font-face { /* this goes in my normal css file */
    font-family: 'Graublau Web';
    src: url(//:) format("no404"),
        url("GraublauWeb.woff") format("woff"),
        url("GraublauWeb.otf") format("opentype"),
        url("GraublauWeb.svg#grablau") format("svg");
    }
</style>

So I use the Mo'Bulletproof syntax in my projects, based on this sort of trial-and-error testing system. Note, I don't usually put these in my HTML files of course, they go in their respective css stylesheets without any conditional comments or HTML tags.

No perfect solution

Whether it's Paul Irish's Bulletproof syntax with a smiley face, or the "url(//:)" in the Mo'Bulletproof-er, both solutions contain code that is only a hack to make IE behave. I don't see a real semantic difference between the two, and I'm OK with double declarations since I have a separate IE stylesheet anyway in my development workflow. In my opinion, the best I can do is to make sure the syntax works for as many users as possible.