Quick Tip: Avoid FOUT by Adding a Web Font Preloader

Quick Tip: Avoid FOUT by Adding a Web Font Preloader

Tutorial Details
  • Topic: Web Fonts
  • Difficulty: Beginner
  • Estimated completion time: 10 mins

FOUT (a Flash of Unstyled Text) is what you’ll often see in that brief moment before a browser has had chance to load and apply web fonts. Typekit and Google Web Fonts offer us a way around this inconvenience – here’s a quick tip to explain exactly how.


Credit goes to Dan for this, after his recent article reminded me of the WebFont Loader. It’s so useful I figured it was worth throwing into a quick tip.


FOUT

What an appropriate acronym (in Dutch it means error). In any case, when you use web fonts, they need to be loaded into your browser as assets (just like images and scripts) which can take a moment. In this situation your browser will look at the font stack..

body {
	font-family: 'Oswald', Arial, sans-serif;
}

..to determine which font should be displayed while the web font (Oswald in this example) is making its journey. Once the web font is available, there’ll likely be a ‘flash’ as the fallback font disappears and the intended font takes its rightful place. Not ideal.


WebFont Loader

The webfontloader script was bashed together by Google and Typekit, and is made available by default with both of their services.

It adds class names to the <html> element to reflect the status of any webfonts being loaded. While loading is taking place, this is applied:

	<html class="wf-loading">

More specifically, classes are added for every font in the pipeline (Droid Serif Normal 400 for example):

	<html class="wf-droidserif-n4-loading wf-loading">

Once the process is complete, these classes are updated:

	<html class="wf-droidserif-n4-active wf-active">

Or in the event of a problem loading the assets:

	<html class="wf-droidserif-n4-inactive wf-inactive">

These classes give us great flexibility in determining what a user experiences at any given point in the web font rendering process. Let’s now build an example to make things perfectly clear.


Step 1: Grab Some Fonts

Okay, I skipped a step, I’m assuming you have an html document to work with. Download the source files and you’ll find a folder called “demo-starting-block”. Open the index.html within it and you’re good to go.

Head on over to Google Web Fonts and select a font or two for use in your project.


Boogaloo should do..

Once you’ve hit “Add to Collection”, head down to the bottom of your screen and hit “Use” where you see a summary of your collection so far.

Whereas normally you might opt to link directly to the css file stored on Google’s gargantuan servers, hit the JavaScript tab and copy the snippet you’re given.

Google suggest you paste this snippet as the first item after the opening <head> tag – and with good reason. It’s important this script is allowed to apply the class names (we spoke about earlier) as soon as possible in order to combat FOUT. If you pulled this JavaScript in after everything else on the page, the fallback font will have been given a chance to rear its ugly head..

Here’s my snippet, safely where it belongs:

<head>
<script type="text/javascript">
  WebFontConfig = {
    google: { families: [ 'Boogaloo::latin' ] }
  };
  (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);
  })(); </script>

Using @font-face

Let’s apply our Boogaloo font to everything on the page (I’m not going for style points here). Open up css/styles.css and kick things off with:

body {
	font-family: 'Boogaloo', cursive;
}

All the actual @font-face jiggery-pokery has been dealt with server-side by Google – we just have to use the value as provided.

Okay, at this point you’ll see the FOUT effect I’ve been banging on about so much (though admittedly *very* briefly). If you want to see it more clearly, try adding hundreds of fonts to your collection, that should slow things down..


Making Use of wf-*

There are all kinds of things you could do to the content on your web page, to specifically reflect the font loading status. Let’s use a pseudo-element to inform users what’s going on.

Continuing on in our styles.css, add an :after pseudo-element to our HTML whilst it has a wf-loading class, like so:

.wf-loading:after {
	/*
	first up, we need
	to define some content
	*/
    content: "loading fonts..";
    /*
    let's now give it some
    dimensions, a background
    color and position
    it on the page
    */
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    /*
    okay, so what do we want
    our label to actually
    look like?
    */
    color: #135040;
    font-size: 1.5em;
    font-weight: bold;
    line-height: 20em;
    text-align: center;
}

We’ve essentially covered the entire page with a huge label, the comments in the CSS should make it clear what’s going on. Here’s a screenshot of what you can see whilst the font is loading:

Of course, once the font has finished loading, the loading classes are removed and replaced with other statuses. The :after pseudo-element ceases to be, revealing the page with your web font applied. No FOUT!


Added Subtlety

The effect we just achieved does its job perfectly, but the label just disappears once the fonts are loaded, abruptly revealing the content beneath. We can improve on that, surely?

Frustratingly, transitions on generated content are still weakly supported so we can’t rely on any tricks there. What we can do is hide all the page content, transitioning it in once the -loaded classes have been applied.

Try this. Get rid of all the styles we just made, placing this at the very top of your css file:

.wf-loading * {
	/*
	first things first, we need to hide everything,
	but bear in mind that this will only take effect
	once the loading script has taken effect.
	here we're hiding all content within
	the <html> once it has the class "wf-loading"
	*/
	opacity: 0;
}
body {
	font-family: 'Boogaloo', cursive;
}

This little nugget is going to hide (through reducing opacity to 0) every element within html.wf-loading. It’s the very first rule, hiding everything before FOUT takes place.

With the content hidden, we can apply a background to our html element.

.wf-loading {
	/*
	here's a background image (at a meer 723bytes)
	to indicate something's happening
	*/
	background: url('../images/ajax-loader.gif') no-repeat center center;
	/*
	just to make sure the <html>
	element shares the same dimensions as
	the browser window when loading
	(and not the potentially elongated page)
	*/
	height: 100%;
	overflow: hidden;
}

We’ve used a loader.gif generated by one of the many online tools available. Obviously, whatever the background you choose, it should be lightweight. There’s no point trying to preload a font file of 20Kb by displaying a graphic of 4Mb..

Now, if we load our page, all the content is hidden, apart from the html.wf-loading with its loader gif background. When the font loads, that gif will vanish.


Bring it Back

The html element has now been assigned other classes, so let’s use those to bring back the invisible content:

.wf-active *,
.wf-inactive * {
	/*
	add some transitional effects
	to reintroduce the content
	gradually once fonts are loaded
	*/
	-webkit-transition: opacity 1s ease-out;
	-moz-transition: opacity 1s ease-out;
	-o-transition: opacity 1s ease-out;
	transition: opacity 1s ease-out;
}

Irrespective of whether the font was successfully or unsucessfully loaded, we’ll need to see our content again. wf-loading releases its grasp on the zero opacity of all elements on the page, so we transition them slowly back in. Again, to slow things down, try adding loads of fonts (or play with the class names in your browser’s element inspector.) Fonts are also stored, so each time you test it you may need to empty your browser’s cache.


Conclusion

Simple, yet effective. My favorite kind of tip. And the possibilities are endless – how would you suggest using the wf-* classes?

Last, but not least, I couldn’t resist this preloader by Kontramax on dribbble. It’s a bit heavy for our purposes, but what the hey!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.creativemanner.com ozgur coruhlu

    Loved it! thanks for introduction…

  • Bennie

    As someone who uses web fonts regularly, and chronically OCD about the little details, this is a perfect solution for what seemed to be an unsolved problem. Thanks for keeping my sites classy!

  • dj

    Nice… works as described… except, a big problem (for me at least). The “subtile” transitioning effect screws up all the transitioning effects downline on my page. I’ve messed with it for almost an hour over all the specificity issues and I can’t seem to get it fixed without a major rewrite – no bueno!

    • dj

      My OC just wouldn’t let this go – Actually, in latest FF – the opacity transition doesn’t seem to work either as given. On my page it doesn’t seem to take very long to load the fonts and the transition is definetly NOT 1 second. It just slams in your face at once. But, like I say, if I increase it the rest of the transitions seem to get irretrevably overridden. [Example: the site]

      • ryanmaurodesign

        Hey DJ I was just having the same problem as you were in that all other css animations were being killed by the inclusiveness of the * selector. My solution was to use specificity to keep the transition styles from cascading to the rest of my site. I have a div that contains ALL of the other elements in the page and I gave it a class of “superwrapper”. Then I replaced all of the * selectors with .superwrapper selector within the .wf-loading wf-active and .wf-inactive rules and like magic the loading animation works and so do my other animations that are defined later in the stylesheet! Let me know if you need me to clarify or provide an example.

    • dj

      @ian … perhaps you understand this better than I. The CSS you gave was tagged to HTML * – and on the web page that I’ve set it up on here I’ve arbitrarily set the opacity for that tag to “5s” to highlite the issue. Further down the code I’ve set a “menu li a div” opacity style as well to 300ms – a nice speed for a menu. The first code over-rode the second (on the menu but NOT on the “font load”) until I put “!important” on the second code. Now with “!important” on the “menu” – the menu fade works as usual except the “loading fonts” still doesn’t seem to have a transition at all, even the short one. Any comments?

      ps – additionally, I’ve never been able to figure out why mousing downward on the menu generates the transition BUT mousing upward from one selection to the other has none. I wrote to FF about it, but received no answer. This is something I’ve puzzled on from day one in spite of using “ease-in-out.”

  • http://www.adipurdila.com AdiPurdila

    Nice one, had no idea this option existed… /hides in shame

    I’ll definitely include it in my future projects.

  • Alex

    Hi,

    By clicking the Demo link First i saw the arial Font and later then the loading Image and the New Font . Is that right? That is the Effect to avoid.

  • http://www.customicondesign.com Custom Icon Design

    Thanks for your introduction. From this article I know we should use google’s javascript kit to load the font, also have some extra css files, I think it will make the website slowly. I prefer to use the normal font face.

  • http://www.themer.me Norris

    I somehow missed web-font preloading, it certainly looks like something I should use.

  • http://think360studio.com/ Think360studio

    Great Tip. I really liked it.

  • http://www.firstbroadcast.co.uk Matt

    I might be at risk of sounding like I’m trying to rubbish this tutorial or that I’ve missed the point – I’m not at all, I thought it was good and could be useful in some instances.

    However, surely you shouldn’t just be picking ugly horrible fallback fonts. A fallback font should still complement the design almost as well as the main font – should the main font not be able to load for some reason. I.e. don’t just pick arial or something when you wanted museo sans as the main font ‘cos it just won’t look right anyway.

    I know the point is to stop the fallback font, whatever it is, from being seen but still, this should also be kept in mind I feel.

  • http://danielfiller.com Daniel

    Been doing this on my site for a while now. Learned the trick from Daniel Eden, who uses it on many of his sites. Good writeup though – hopefully more people begin to do this. Although, I can see it being abused with ridiculous transition effects. :]

  • http://egegorgulu.com Ege

    I strongly disagree with what this post is trying to achieve. Yeah, no FOUT would be great but hiding the whole content just to prevent it is an overkill.

    The content is king on the internet, remember?

    • http://www.rackservers.com.au Rob RS

      the extra time taken for web fonts to load could appear like there’s an issue with the site – it’s a balance between aesthetic and wait time i suppose

  • http://www.richardmisencik.com Richard

    Great idea, might be pretty useful on some bigger projects when using multiple fonts. I will definitely use this, thanks much!

  • Pingback: Tweet Parade (no.34 Aug 2012) | gonzoblog.nl

  • http://sean.gravener.net Sean Gravener

    Great tip, Ian! Like you said: Simple, yet effective. You can bet I’ll be using this one.

  • Pingback: Working With WebINK: Pro-Quality Fonts for the Web | Webdesigntuts+

  • Pingback: Behind the themes – designing and developing Netskills Voices | Netskills Voices