Trevor Burnham

Sure, it works in practice…

Flicker-​​free Typekit

January 28th, 2010

[Update: On May 14th, 2010, Typekit finally announced an official solution to the “flash of unstyled text” problem. So, the fix below should be con­sid­ered obsolete.]

I’m a fan of Typekit. Being able to go beyond the old Arial-​​Verdana-​​Times-​​Georgia paradigm, on any modern browser, without Flash (unlike sIFR), and with selec­table text (unlike Cufón), is a dream come true.

One problem, though: It takes a few mil­lisec­onds to load up and render those fonts. That’s not so bad in itself; what’s bad is that the browser renders every­thing in non-​​Typekit fonts first, creating an annoying flicker every time the page loads as the text gets replaced by fancier fonts.

For­tu­nately, there’s a fairly easy solution (though not an offi­cially sup­ported one—see below). Just add this to your site body:

1
2
3
4
5
6
7
8
9
10
11
12
13
<body id="domain-com">
  <script type="text/javascript" src="http://use.typekit.com/KIT_ID.js"></script>
  <script type="text/javascript">
    document.getElementById('domain-com').style.opacity = 0;
    setTimeout("document.getElementById('domain-com').style.opacity = 1", 1000);
    Typekit.load('KIT_ID', {
      afterLoad: function(data) {
      	setTimeout("document.getElementById('domain-com').style.opacity = 1", 1);
      }
    });
  </script>
  <!-- content goes here --> 
</body>

Then sub­sti­tute your actual domain for domain-com, and (impor­tant!) your site’s unique Typekit ID for KIT_ID. You can get this ID by logging in to Typekit, launch­ing the Kit Editor, and clicking the “Embed Code” link; it’s an 8-​​letter alphanu­meric combination.

Here’s a breakdown:

  1. The <body> ID on line 1 isn’t just a good selector; it’s good form. The most common con­ven­tion is to use your domain (with a dash instead of a dot), which makes things easier for the Grease­mon­key types.
  2. The script include on line 2 brings in the Typekit descrip­tion of your site’s kit. You can move this line up to your <head> section if you want.
  3. Line 4 makes your entire site dis­ap­pear. Because this is at the top of your body, nothing is going to get rendered. It’s impor­tant that this line be here, rather than in another file or even at the foot of your body.
  4. The call to Typekit.load does the actual loading of the fonts, and the afterLoad callback will be executed right after that happens. That’s when we want to make the body opaque again, right? Well, not quite. It seems that there’s a small delay between the callback and text refresh. For­tu­nately, using setTimeout to add a tiny delay (1ms) seems to elim­i­nate this, finally ridding us of the dreaded flicker.

Caveat: The afterLoad event is cur­rently con­sid­ered exper­i­men­tal. An official solution for avoiding flicker is likely to be added in the future.

Tags:       2 Comments

2 responses so far ↓

  • This was EXACTLY what I was looking for. Well ok, an offi­cially sup­ported solution is what I was looking for, but until then… I really appre­ci­ate it.

    I think having the whole site content appear at once is kinda strange, but not nec­es­sar­ily bad. WAY better than the default font for 1 second, followed by the typekit fonts.

    • Delighted to hear it! Nat­u­rally, you can use a narrower selector if you want. Or, if you’re using Typekit for a full-​​fledged Gmail-​​style webapp (with a sig­nif­i­cant loading time from other libraries), you could have an Ajax loading graphic run until the Typekit after­Load event has fired and every­thing else is set to go as well.

      For most sites, I think that having a few hundred ms of loading time followed by every­thing falling into place at once is more appeal­ing than having the page flicker into exis­tence one piece at a time.