Web fonts give us designers a whole new typographic palette with which to work. However, browsers handle the loading of web fonts in different ways, and this can lead to inconsistent user experiences.
Safari, Chrome and Internet Explorer leave a blank space in place of the styled text while the web font is loading. Opera and Firefox show text with the default font which switches over when the web font has loaded, resulting in the so-called Flash of Unstyled Text (aka FOUT). Some people prefer Safari’s approach as it eliminates FOUT, others think the Firefox way is more appropriate as content can be read whilst fonts download. Whatever your preference, the WebFont Loader can make all browsers behave the same way.
The WebFont Loader is a JavaScript library that gives you extra control over font loading. It was co-developed by Google and Typekit, and released as open source. The WebFont Loader works with most web font services as well as with self-hosted fonts.
The WebFont Loader tells you when the following events happen as a browser downloads web fonts (or loads them from cache):
- when fonts start to download (‘loading’)
- when fonts finish loading (‘active’)
- if fonts fail to load (‘inactive’)
If your web page requires more than one font, the WebFont Loader will trigger events for individual fonts, and for all the fonts as a whole. This means you can find out when any single font has loaded, and when all the fonts have loaded (or failed to do so).
The WebFont Loader notifies you of these events in two ways: by applying special CSS classes when each event happens; and by firing JavaScript events. For our purposes, we’ll be using just the CSS classes.
Implementing the WebFont Loader
As stated above, the WebFont Loader works with most web font services as well as with self-hosted fonts.
Self-hosted fonts
To use the WebFont Loader when you are hosting the font files on your own server, paste the following code into your web page:
<script type="text/javascript">
WebFontConfig = {
custom: { families: ['Font Family Name', 'Another Font Family'],
urls: [ 'http://yourwebsite.com/styles.css' ] }
};
(function() {
var wf = document.createElement(‘script’);
wf.src = (‘https:’ == document.location.protocol ? ‘https’ : ‘http’) + ‘://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js’;
wf.type = ‘text/javascript’;
wf.async = ‘true’;
var s = document.getElementsByTagName(‘script’)0;
s.parentNode.insertBefore(wf, s);
})();
Replace Font Family Name and Another Font Family with a comma-separated list of the font families you want to check against, and replace http://yourwebsite.com/styles.css with the URL of the style sheet where your @font-face rules reside.
Fontdeck
Assuming you have added some fonts to a website project in Fontdeck, use the afore-mentioned code for self-hosted solutions and replace http://yourwebsite.com/styles.css with the URL of the <link> tag in your Fontdeck website settings page. It will look something like http://f.fontdeck.com/s/css/xxxx/domain/nnnn.css.
Typekit
Typekit’s JavaScript-based implementation incorporates the WebFont Loader events by default, so you won’t need to include any WebFont Loader code.
Making all browsers behave like Safari
To make Firefox and Opera work in the same way as WebKit browsers (Safari, Chrome, etc.) and Internet Explorer, and thus minimise FOUT, you need to hide the text while the fonts are loading.
While fonts are loading, the WebFont Loader adds a class of wf-loading to the <html> element. Once the fonts have loaded, the wf-loading class is removed and replaced with a class of wf-active (or wf-inactive if all of the fonts failed to load). This means you can style elements on the page while the fonts are loading and then style them differently when the fonts have finished loading.
So, let’s say the text you need to hide while fonts are loading is contained in all paragraphs and top-level headings. By writing the following style rule into your CSS, you can hide the text while the fonts are loading:
.wf-loading h1, .wf-loading p {
visibility:hidden;
}
Because the wf-loading class is removed once the the fonts have loaded, the visibility:hidden rule will stop being applied, and the text revealed. You can see this in action on this simple example page.
That works nicely across the board, but the situation is slightly more complicated. WebKit doesn’t wait for all fonts to load before displaying text: it displays text elements as soon as the relevant font is loaded.
To emulate WebKit more accurately, we need to know when individual fonts have loaded, and apply styles accordingly. Fortunately, as mentioned earlier, the WebFont Loader has events for individual fonts too.
When a specific font is loading, a class of the form wf-fontfamilyname-n4-loading is applied. Assuming headings and paragraphs are styled in different fonts, we can make our CSS more specific as follows:
.wf-fontfamilyname-n4-loading h1,
.wf-anotherfontfamily-n4-loading p {
visibility:hidden;
}
Note that the font family name is transformed to lower case, with all spaces removed. The n4 is a shorthand for the weight and style of the font family. In most circumstances you’ll use n4 but refer to the WebFont Loader documentation for exceptions.
You can see it in action on this Safari example page (you’ll probably need to disable your cache to see any change occur).
Making all browsers behave like Firefox
To make WebKit browsers and Internet Explorer work like Firefox and Opera, you need to explicitly show text while the fonts are loading. In order to make this happen, you need to specify a font family which is not a web font while the fonts load, like this:
.wf-fontfamilyname-n4-loading h1 {
font-family: 'arial narrow', sans-serif;
}
.wf-anotherfontfamily-n4-loading p {
font-family: arial, sans-serif;
}
You can see this in action on the Firefox example page (again you’ll probably need to disable your cache to see any change occur).
And there’s more
That’s just the start of what can be done with the WebFont Loader. More areas to explore would be tweaking font sizes to reduce the impact of reflowing text and to better cater for very narrow fonts. By using the JavaScript events much more can be achieved too, such as fading in text as the fonts load.


Comments
Comments are ordered by helpfulness, as indicated by you. Help us pick out the gems and discourage asshattery by voting on notable comments.
Got something to add? You can leave a comment below.
02/12/2010
Superb article, I’ll definitely consider this when implementing web fonts.
Nice.
Vote Helpful or Unhelpful
02/12/2010
Thanks for this great article, Richard! WebFont Loader is perfect JS library I was just looking for …
Vote Helpful or Unhelpful
02/12/2010
great tip here. now if only i could get all the designers to use web fonts…
Vote Helpful or Unhelpful
02/12/2010
Great information, I’ve been toying with font replacement on several websites lately and it is annoying how the major browsers just don’t act uniformly. I will for sure start trying to implement this as a standard. Thanks for the great writeup!
Vote Helpful or Unhelpful
02/12/2010
I’m working on a new theme for my wordpress-powered blog and I want to make it typographically appealing. This is exactly what I need so that I could use those WebFont that I been wanting to use. Thank you.
Vote Helpful or Unhelpful
02/12/2010
Hmmmm… I might use the javascript events to write a cookie or client side storage flag and only display the font-face typeface on the 2nd page load. I’d actually prefer that to a switcheroo of any form… Webkit’s or firefox’s; both feel like spasms to me.
Cool write-up, Richard. :) thanks!
Vote Helpful or Unhelpful
02/12/2010
I had never heard of the WebFont Loader, but it is a really good idea. I will definitely read more about it.
Thanks for the tip Richard.
Vote Helpful or Unhelpful
02/12/2010
What, no comments? This post has been up for hours!
The whole way through the article I had this idea that I wanted to share in the comments, and then you chucked it in there at the very end. Very “one more thing”- esque :-)
Regarding the FOUC vs. nothing-then-show dilemma, I think the option that involves the most work will be worth a try. Sticking to displaying the text while we’re waiting for the font(s) to download, and styling it so there’s no reflow of text etc. And possibly even do a fade transition from one font to the other.
Any other pros or cons?
Vote Helpful or Unhelpful
02/12/2010
This is a really nice, useful write-up, as we are just starting to utilise web fonts. However (and forgive me if I am mistaken about this), it would be even nicer if it worked with the CSS @font-face declaration, giving you some non-JS backup. Can this be done here?
Hope I don’t sound TOO negative about the article, as it provides a very useful answer to the ‘evil’ (in many people’s eyes!) FOUT :)
Vote Helpful or Unhelpful
02/12/2010
But no @font-face action with JavaScript turned off? I can see though how it would be a favourable solution when FOUT is particularly glaring. Thanks for the tip off about this script.
Vote Helpful or Unhelpful
02/12/2010
Ahhh, 24Ways – best thing about Christmas! (whilst stuck at work at least…)
This is a great snippet to roll into my starter files. I wonder if this could be put onto the to-do list of Modernizr? Marking support / status as a JS modified CSS class on the opening HTML tag is a really neat way of doing things.
Regards, Karl
Vote Helpful or Unhelpful
02/12/2010
I had no idea about this script. How fantastic that we can decide upon the behaviour of loading our fonts, and even extend it. This will certainly be making it in to my boilerplate along with Selectivzr and Modernizr. This was an eye opener, and a nice introduction. It would have been nice to of seen some of the other features that can be achieved, however I will be investigating and playing with these. Great article, thanks.
Vote Helpful or Unhelpful
02/12/2010
Nice but no JS = no @font-face?
=(
Vote Helpful or Unhelpful
02/12/2010
Wow! Such a great and useful article!
I will for sure consider it for my future website design project if I have to use web fonts! Such a life-saver!
Thanks for sharing! :)
Vote Helpful or Unhelpful
02/12/2010
Ahh, a very useful solution I was not even aware of. Fantastic. Will definitely be putting this to use in my web projects.
Thanks for a great and informative article.
Phil
Vote Helpful or Unhelpful
02/12/2010
Brilliantly succinct and well-explained. Nice work, Rich!
Vote Helpful or Unhelpful
02/12/2010
Excellent article, never heard of this. 24ways is definitely of to a great start.
Two great tips (including yesterday’s) Implemented in two mins make for a fantastic user experience .
Why is it the authors here do so well in our industry … oh yes I know…
Thanks Richard
Vote Helpful or Unhelpful
02/12/2010
To avoid making fontface dependent on js, just apply a .nojs to your body and remove it via js asap.
Then add to your css a rule forcing the fontface:
.nojs h2, .nojs p { visibility: visible; }
This way you fallback for the FOUT version, but with no js it’s kinda of acceptable, no?
Vote Helpful or Unhelpful
02/12/2010
I loved Web Font Loader and confess never heard a thing about it, but I missed the Progressive Enhancement part, why not check if we have support to JS so we load Font Loader, otherwise just load the .css with @font-face declaration, I think that’s a better approach, isn’t?
December really is the month of learn new cool web stuffs.
Vote Helpful or Unhelpful
02/12/2010
I always felt like FOUT was something that only bugged me. I tip my hat to this article.
Vote Helpful or Unhelpful
02/12/2010
I can’t believe that I never knew about this! Excellent stuff.
Vote Helpful or Unhelpful
02/12/2010
Just use the font face generator. Works without JS and on all popular browsers : CSS only.
http://www.fontsquirrel.com/fontface/generator
Vote Helpful or Unhelpful
02/12/2010
If you are worried about the @font-face not working without Javascript, just wrap your old CSS link tag in noscript tags.
Vote Helpful or Unhelpful
02/12/2010
Awesome article. I have just started using self-hosted webfonts. This article will definitely help me ensure all users have the same experience regarding fonts. Thanks.
Vote Helpful or Unhelpful
03/12/2010
The automatic implementation in just another reason why I love Typekit!
Vote Helpful or Unhelpful
03/12/2010
What an awesome way to take control of FOUT – this is definitely going into my projects by default!
Vote Helpful or Unhelpful
03/12/2010
Hmm… I like the idea of this but whether it’s actually a good idea to alter the default behaviour of someone’s browser, I don’t know.
Vote Helpful or Unhelpful
03/12/2010
A great article, playing around with css3 and experimenting with web fonts – this is a good way to create a good standardised UX. I’m going to implement this in a project I’m working on right now.
Cheers.
Vote Helpful or Unhelpful
03/12/2010
Excellent article. I was not aware of the existence of this JavaScript library, nor have I ever thought about the possibility of detecting when a font has finished downloading.
Thanks.
Vote Helpful or Unhelpful
04/12/2010
Regarding the no JavaScript situation, I never said not to include a regular HTML link to the CSS file – yes you really should do this. As Nathan said in the comments you could wrap this in noscript tags, but it’s not really necessary to do so.
Vote Helpful or Unhelpful
06/12/2010
Perfect – thanks.
Vote Helpful or Unhelpful
06/12/2010
Thanks for sharing. I already try to play with Google Font API and it’s very simple to use… But for large projects or ecommerce websites I would advise not to use this technique because it slows down (a little) the page loads, which can lead to a lower rate of conversion
Vote Helpful or Unhelpful
07/12/2010
I really like the idea of being able to style the fallback text to minimise reflow.
I don’t agree with the notion of changing a browsers default behaviour though.
Whether FOUT is acceptable or not should not be decided by the designer, but by the user. Some users might find it very disturbing, while others might need it because downloading large fonts over a slow connection would make their browsing too slow otherwise.
Therefore it is a good thing that browsers behave differently, although preferably all browsers should have a setting to let the user control the behaviour.
Vote Helpful or Unhelpful
08/12/2010
Nice article, txs.
In both Chrome 8 and latest Chromium 10 build, myself and a friend clearly see the FOUT happen on your Safari test page (http://24ways.org/examples/2010/using-webfont-loader/safari.html). That surprised me. Can you/anybody please confirm and hopefully explain why this happens? Webkit should not do the FOUT
Vote Helpful or Unhelpful
25/12/2010
I just tested it on an old project’s pages which had this disturbing issue, it works perfectly :-)
Brilliant solution. Thank you!
I would love to propose this solution to any client who cares about FOUT more than an additional HTTP request, and a 13K JS file.
Vote Helpful or Unhelpful
05/12/2012
I guess that’s FOUC (Flash of Unstyled Content), not FOUT. Anyway, I guess both pros and cons arguments are powerful enough.
Vote Helpful or Unhelpful
Impress us