Combining Cufón and @font-face

CSS & HTML, 6 April 2009, 43 comments

Everyone wants @font-face to work everywhere, but as it stands, it only works in Safari and the upcoming versions of Firefox and Opera. In this article I’ll show you how to use Cufón only if we can’t load the font through other, faster methods.

If you’re not familiar with Cufón, check out my previous article: Cufon vs. Typeface.js, which one is better? or this article: Exploring Cufón, a sIFR alternative for font embedding by Cameron Moll.

Not just @font-face…

Now, @font-face isn’t the only way to display custom fonts. What if the visitor already has the font installed? It’ll display automatically then, again leaving us with no reason to use load Cufón. These are the three options you have when you want to display custom fonts, in order of speed:

I will not go into @font-face in this post, for more on web fonts, read these articles: CSS at ten and @font-face in IE: making web fonts work (Which not only explains how to use @font-face in browsers that support it, but also in IE using their proprietary DRM-ed .eot ‘standard’.)

The trick

The effect of an installed font and using @font-face are the same: The font is rendered and displayed natively by the browser. This means that you only have to check if the font is available, and can forgo checking if @font-face is at all an option. A very smart solution to do this is the jQuery fontAvailable plugin. The implementation looks like this:

$(document).ready(function() {
    if($.fontAvailable('Optimer')) {
        // code here
    }
});


The plugin works in a most ingenious way: On document load, it created an element with the alphabet in it, and sets the font-family to a non-existent font to apply the default font. It then replaces the font-family with the font you've specified, and checks if the width has changed. If the width has changed, that means the font was applied and is available.

Update: Eneko Alonso ported the plugin to mootools: moo-fontavailable. Cool no?

So, all you have to do to make this work, is make sure that the font-name you define in your @font-face declaration is the same as the real font name, and it will automatically work for both already installed fonts, and fonts loaded in with @font-face!

And then Cufón

So, with an @font-face declaration in your CSS, and a bit of JavaScript telling you if the font is available, all you have to do is add in @cufón when $.fontAvailable returns false! (Note the added ! in the example code, so Cufón gets executed if the font is not available)

$(document).ready(function() {
    if(!$.fontAvailable('Optimer')) {
      Cufon.replace('h1');
    }
});

Unfortunately it's not quite that easy. Because IE can show a FOUC with Cufón, you have to add Cufon.now(); at the end of the page. If we use Cufón from within $(document).ready();, that would make Cufon.now(); ineffective because it would actually be parsed before the document is ready, and thus before the initial Cufon.replace(); function.

It will still work, but IE users might see the font getting changed while the page is loaded. Over at the Google group, they are already working on a solution to this, so it shouldn't be long before you won't need Cufon.now(); at all anymore.

That's all there is to it

All in all, it's quite simple. Check if the font is available, either through already being installed or through @font-face, and if it isn't, we'll let Cufón display it. This offers you the best of both worlds, because browsers that support @font-face will have their native text, and browsers without @font-face support will still get custom fonts.