Introduction to the Google WebFont Loader

by Cedric Dugas on July 27, 2010

You remember the “old days” when you were cursing at sIFR because it would not give you the font-size you wanted, did text flickering on page load or was just not working at all on IE? Well those days are all gone, the introduction of Cufon sometime ago solved most of the sIFR issues, but one of the big downside was that you could not select the text anymore.

Now with @font-face we finally got a native way of using custom fonts in our websites. Unfortunately this is not as easy as it should be. This is probably why Google launched recently the Google WebFont Loader and the Google font directory. Two easy way of using @font-face without any trouble, well, less trouble.

The text flickering problem all over again

@font-face suffers of the same illness that its predecessors, until the font file is loaded it will display your text with the fallback font family. When you know that 20px with an hand written font can be a lot smaller than 20px with Arial, this becomes a major problem, you don’t want to see an enormous text until your custom font is loaded.

Google WebFont Loader at the rescue

I will be showing how you can use the google font loader to avoid text flickering and have a good fallback font in case the font file is not loading. You get the best of all world, but it comes with a price of a light javascript hack.

Getting started

Using the basic google font ability is easy (but it is quite a bunch of lines of code), you just embed the font you want!

  1.  <script type="text/javascript">
  2.       WebFontConfig = {
  3.         google: { families: [ 'Tangerine', 'Cantarell' ] }
  4.       };
  5.       (function() {
  6.         var wf = document.createElement('script');
  7.         wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
  8.             '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
  9.         wf.type = 'text/javascript';
  10.         wf.async = 'true';
  11.         var s = document.getElementsByTagName('script')[0];
  12.         s.parentNode.insertBefore(wf, s);
  13.       })();
  14.     </script>

As you can see, in this example you just need to change this line google: { families: [ 'Tangerine', 'Cantarell' ] } for the font you want from the Google Font Directory (other fonts are also available like those from typekit.com). There is also quite a bunch of options you can use, have a look at the loader API for more information.

Now this script does one thing interesting, it adds a css class to your document html, it will add wf-loading until the font is loaded, wf-inactive if it can’t load the font, and wf-active when it’s successful. We can use this at our advantage. You can provide a valid CSS fallback that protect yourself from enormous and actually define your fallback font instead of being dependent of the same line-height and font-size.

An example

  1. <head>  
  2.  <script type="text/javascript">
  3.        WebFontConfig = {
  4.          google: { families: [ 'Tangerine', 'Reenie Beanie' ] }
  5.        };
  6.        (function() {
  7.          var wf = document.createElement('script');
  8.          wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
  9.              '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
  10.          wf.type = 'text/javascript';
  11.          wf.async = 'true';
  12.          var s = document.getElementsByTagName('script')[0];
  13.          s.parentNode.insertBefore(wf, s);
  14.        })();
  15.      </script>
  16.    
  17.        <style type="text/css">
  18.        p {
  19.          font-family: arial;
  20.          font-size:20px;
  21.                 line-height:22px;
  22.        }
  23.        h1 {
  24.          font-family: serif;
  25.          font-size: 22px;
  26.        }
  27.        .wf-loading p {
  28.          visibility:hidden;
  29.        }
  30.        .wf-loading h1 {
  31.          visibility:hidden;
  32.        }
  33.        .wf-inactive p, .wf-inactive h1{ visibility:visible;}
  34.  
  35.        .wf-active p {
  36.          font-family: 'Tangerine', serif;
  37.          font-size:33px;
  38.                 line-height:26px;
  39.        }
  40.        .wf-active h1 {
  41.          font-family: 'Reenie Beanie', serif;
  42.          font-size: 33px;
  43.        }
  44.      </style>
  45.  </head>
  46.  <body>
  47.   <h1>This is a title with a custom font</h1>
  48.   <p>No text flickering and got the somewhat the same font height in fallback</p>
  49.   <p>View the source to have a look at the code</p>
  50.  </body>

View demo

In this example we can see that we have a very good font-size fallback we use wf-active to set our custom font, and we just do our normal css flow as a fallback.

A flicker you say?

The text still flicker a bit at random times, specially in IE, this is because, wf-loading is added when the javascript file from Google is parsed in the document, and for some reasons (I guess it is a bug), even is we put async false, sometimes the wf-loading class is added to late.

The best way to avoid the flicker behavior is to add a class wf-loading to the html document in javascript ourself, you then add the rule visibility:hidden in css to it, and on .wf-inactive and .wf-active you simply add visibility:visible, the same css rules added in the last example. This way if the font can’t be loaded we will receive the wf-inactive and the text will be displayed.

With this solution your users with javascript disabled will still see your text with your normal fonts.

(This solution has been updated, Thanks to Paul Irish idea in the comments section)

  1.          <script>
  2.        (function() {
  3.         document.getElementsByTagName("html")[0].setAttribute("class","wf-loading")
  4.   //  NEEDED to push the wf-loading class to your head
  5.   document.getElementsByTagName("html")[0].setAttribute("className","wf-loading")
  6.         // for IE…
  7.  
  8.          var wf = document.createElement('script');
  9.          wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
  10.              '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
  11.          wf.type = 'text/javascript';
  12.          wf.async = 'false';
  13.          var s = document.getElementsByTagName('script')[0];
  14.          s.parentNode.insertBefore(wf, s);
  15.        })();
  16.      </script>
  17.     <style type="text/css">
  18.         p {
  19.          font-family: arial;
  20.          font-size:20px;
  21.        }
  22.        h1 {
  23.          font-family: serif;
  24.          font-size: 22px;
  25.  
  26.        }
  27.        .wf-loading p {
  28.          visibility:hidden;
  29.        }
  30.        .wf-loading h1 {
  31.          visibility:hidden;
  32.        }
  33.        .wf-inactive p, .wf-inactive h1{ visibility:visible;}
  34.        .wf-active p {
  35.          font-family: 'Tangerine', serif;
  36.          font-size:33px;
  37.          visibility:visible;
  38.        }
  39.  
  40.        .wf-active h1 {
  41.          font-family: 'Reenie Beanie', serif;
  42.          font-size: 33px;
  43.         visibility:visible;
  44.        }
  45.      </style>

View demo

That’s it

Hope it will help you guys get your custom fonts working as you want!

26 comments

Cool article.

Have you tested it in any CSS heavy website yet? I see you eliminated the font replacement flickering but it is invisible on page load. I’d be interested to see how it looks when there are a lot of images/css to load.

by Stéphane Caron on July 28, 2010 at 7:59 am. Reply #

Nice article.

Have you experience difference between browser? In my case, i’ve seen a lot of differences between Firefox, IE, Chrome and Safari and more betweens OS, specially for anti-alias.

by Dominic Mercier on July 28, 2010 at 8:25 am. Reply #

I honestly can’t imagine a situation where a little bit of flicker is worse than text being completely invisible for non-javascript users.

by Ian on July 28, 2010 at 10:29 am. Reply #

This is the solution I came up with for the FOUT/flicker.

The basic script:

WebFont.load({
google: {
families: ['Molengo']
}
});

The CSS.

.wf-loading .post h2 { visibility: hidden; }
.wf-active .post h2, .wf-inactive .post h2 {
visibility: visible; font-family: ‘Molengo’;
}

.wf-loading is applied before the page is visible, so no peek at the old font. Plus, nothing is hidden if javascript is disabled.

by Paul Irish on July 28, 2010 at 11:08 am. Reply #

@Paul thank, I am just wondering how you can be sure this is applied before the page is rendered, you add this to your html tag from the head? I am gonna try this and update the article

I tested it on a heavy website, soon to be released, and what happens is your site will render and your text with custom font will render with a delay of 1 to 2 sec (approx)

@Dominic the font will always look weird in FF XP, because there is no antialiasing applied on it. From what I saw, the fonts look good everywhere else.

by Cedric Dugas on July 28, 2010 at 12:33 pm. Reply #

@Cedric, .wf-loading is added right when the webfont loader js is included. So if its in the head, then the page isnt visible yet. You don’t personally need to add that class, the loader does it for ya.

As for type rendering quality. FF<4 on windows is typically pretty ugly. It's a complicated problem but people are trying to fix it. :)

by Paul Irish on July 28, 2010 at 1:28 pm. Reply #

Well that is not entirely true,

You see the font flicker until the js file is loaded from google even if it is in the head. It flicker in ie even if I put async false anyway
but I will update the article again adding this bit of information :P

It is also unfortunate that wf-loading is not mentioned in the Google webfont loader doc, you need a sharp eye to see it in firebug ;)

by Cedric Dugas on July 28, 2010 at 1:39 pm. Reply #

Interesting article. Nice overview of how to use the loader API. Unfortunately, with the demo page, I still see flickering under Chrome. Anyone else experienced this or have an idea for a fix?

by Michael Mior on July 29, 2010 at 4:51 pm. Reply #

@michael you actually saw, in the second example, the default font? or just the spacing moving? I did not bother with adjusting the spacing, but you just need to correct it with wf-loading.

Just tested it with chrome and I didn’t saw the default font, but I got a fast computer, I will try on my netbook later..

by Cedric Dugas on July 29, 2010 at 7:03 pm. Reply #

I see the default font, sometimes for at least half a second before the other font loads. My machine is no slouch. Dual core 2.4 GHz processors with 4GB of RAM. (btw, I’m running Chrome 5.0.375.125 beta and Ubuntu Lucid Lynx in case you’re wondering :)

by Michael Mior on July 30, 2010 at 11:00 am. Reply #

Will have a look, I was sure I nailed it down, but it could be a Chrome ubuntu prob

by Cedric Dugas on July 30, 2010 at 4:44 pm. Reply #

Well written and helpful article.

Apart from using less scripts, minimizing CSS, and trying to compress your code/images, are there any other tricks that might make custom fonts load faster, to avoid the flicker? What if you called the font script before anything else in the head?

by Tanner Christensen on August 1, 2010 at 5:04 pm. Reply #

nice nice :)

by Beben on August 2, 2010 at 7:24 am. Reply #

Nice post.
I think you can replace
document.getElementsByTagName(“html”)[0]
by the document property
document.documentElement

by Mr.MoOx on August 3, 2010 at 7:42 am. Reply #

You might want to check the issues of the different Font servers available out there. Google included.
http://lab.pheromone.ca/2010/06/02/comparison-webfont-services/

by karl on August 5, 2010 at 3:15 pm. Reply #

Interesting, I didn’t know Pheromone had a such in depth blog.

Still the interesting part with the google web font loader is that you are not limited to the google font directory, it makes it easy to load your custom fonts from your own cdn and also from other providers as well.

by Cedric Dugas on August 6, 2010 at 3:47 pm. Reply #

This is pretty exciting news however I noticed when I tried to implement this on a project that the FOUT in FF was indeed hidden, however there was a briefer flash that appeared on every page. I think the flash was the result of going from loading to active very quickly. So two questions.
1. Is there a way to bypass the check once you have the fonts locally (I doubt it).
2. Can you recommend a way to target just FF?
Cheers,
Eric

by Eric Curtis on August 20, 2010 at 11:11 am. Reply #

Great article. Is there anyway to apply this technique to font files located on your own server?

by Julian on October 31, 2010 at 9:37 am. Reply #

What about the performance and will it be compatible to all browsers. Thanks,

by virginia traffic attorney on November 21, 2010 at 2:35 pm. Reply #

The web world has too much to explore, everyday new things are coming up,. There is so much in advancement in technology.

by cat funny videos on December 1, 2010 at 1:35 pm. Reply #

I’m using Chrome on Windows (8.0.552.224) and the flicker on “View Demo” link is significant (0.5 to 1 sec) I tried it on Firefox 3.6 and the same thing (about a 2-second showing of the serif font version before the cache made it faster to load).
I then tried IE8 and the same thing.

I respect your attempt, but how can I judge this any other way than to say “it doesn’t work”.

What browser did you use to give you the impression that it does work?

by PandaWood on January 10, 2011 at 5:56 am. Reply #

What do you mean by flicker? I corrected the fact you were seeing the other font (fouc) for a brief instant. But your going to see a blank space until the font is loaded,

There is no way around this,

by Cedric Dugas on January 10, 2011 at 7:27 am. Reply #

Really great article…

by Wiyono on March 28, 2011 at 10:17 am. Reply #

Соберем для Вас по сети интернет базу данных
потенциальных клиентов для Вашего Бизнеса
(название, телефон, факс, email, сайт, имена и др информацию)
Много! Быстро! Точно!
Узнайте более подробную информацию по:
Телефон +79133913837
ICQ: 6288862
Skype: prodawez3837
Email: prodawez@mixmail.com

by Phypevulley on April 17, 2011 at 8:49 pm. Reply #

After read blog topic’s related post now I feel my research is almost completed. happy to see that.Thanks to share this brilliant matter.

by hollister uk on July 19, 2011 at 1:07 am. Reply #

[...] das angesprochene nennt sich FOUT. Ev. helfen dir diese Artikel weiter: How to Bulletproof @font-face Web Fonts Position Absolute – Introduction to the Google WebFont Loader [...]

by Ladereihenfolge von Webfonts - XHTMLforum on February 25, 2012 at 10:40 am. Reply #

Leave your comment

Required.

Required. Not published.

If you have one.