Web Font Tune-up Time: A Fun Font Fallback Event

J

Jason Pamental in Archive on August 22, 2011

In my last article I talked about the importance of font fallbacks when using Web fonts – though truth be told, it’s important no matter what. But simply adding fallbacks to your CSS leaves a lot of loose ends lying about that are just waiting to trip up you and your users. Here we’ll go through exactly what to do, how to do it and why it’s important to address getting your fallback embedding and styles sorted out and just a bit more complete.

Adding the JavaScript code to your page to add the fonts is a one-line affair – but utilizing Font Events requires a few more. Then you have to ensure you’re making use of those Font Events in your CSS in order to mitigate the vagaries of how browsers render the page during the font loading process – which may be nearly instant, but often will still be noticeable and even a bit jarring. What’s more, while increasingly infrequent, lack of JavaScript (JS) support does occur – and if you don’t account for that with a ‘<noscript>’ option to load your Web fonts, all your efforts will be for naught. All this may seem daunting at first, but fear not! It’s not really that much extra effort and we’re about to go through it, sample code and all.

So let’s review what happens when a page is requested, how it loads and where the pitfalls occur.

  1. A user requests a page from your site
  2. The page begins to load, including a reference to a JavaScript file to embed the fonts. One of two things happens when the script loads:
    1. JS is enabled, so the script runs -OR-
    2. JS is not enabled, so nothing more happens (unless you have cleverly inserted something in a '<noscript>' block below)
  3. Next, one of three things occur:
    1. If JS has run, fonts are loading and Font Events are firing. CSS classes such as ‘wf-inactive’ are being inserted dynamically into your page and you, as a clever designer and/or developer have added to your CSS classes and declarations to help ensure that your text is rendering well both during and after the loading occurs.
    2. If JS has not run but you are indeed clever, the '<noscript>' block containing a link to a CSS file is taking care of loading your fonts and while no Font Events will help mitigate display oddities during the loading process, in a moment or two all will be loaded and displaying according to your design.
    3. If JS has not run but you have not included the '<noscript>' block, while no kittens will be harmed, you will have doomed your users to a far more pedestrian experience likely filled with poorly letter-spaced text set in Arial. You can do better!

Now in the above sequence of events you’ll notice that not only have we accounted for fallbacks should the fonts not load but we’ve even created a fallback scenario for JavaScript not functioning and added a link to CSS that will load the fonts anyway. Very clever indeed. Your mother would be proud. (Unless you have fallen into that last case – but you still have time to redeem yourself!)

For our demonstration I’ve selected a lovely passage from Moby Dick – a tremendous work which also happens to be unencumbered by copyright restriction and therefor an ideal candidate for our use. The PMN Caecilia® and ITC Obliqua™ typefaces made for a nice pairing of headers and body copy, even while imparting a slightly more modern feel juxtaposing the vintage of the text itself. We’ll now dispense with the preliminaries and get down to the business end of things.

Demonstration Page, Fonts Loaded:

Fallback fonts demo - Web fonts on

In order to finish our preparations it’s necessary to accumulate a few bits and bobs of code. You’ll need to log in to your Fonts.com Web Fonts account, go to your project (or create one using this sample one!), navigate to the ‘publish’ tab and copy the two strings presented under ‘Option 1: JavaScript’ and ‘Option 2: Non-JavaScript’. (You will need a Standard or Professional subscription in order to access the Non-JavaScript publishing method). They will look something like this:

<script type=”text/javascript” src=”http://fast.fonts.com/jsapi/f4ed33fe-8f54-42a8-9cec-712422e7fab0.js”></script>

and

<link href=”http://fast.fonts.com/cssapi/f4ed33fe-8f54-42a8-9cec-712422e7fab0.css” rel=”stylesheet” type=”text/css” />

While you’re there, you may as well grab the sample font declarations to use in your CSS:

font-family:’PMNCaeciliaW01-55Roman’;
font-family:’PMNCaeciliaW01-56Italic’;
font-family:’PMNCaeciliaW01-75Bold’;
font-family:’PMNCaeciliaW01-76BoldIt’;
font-family:’Obliqua ITC W01′;
font-family:’Obliqua ITC W01 Italic’;
font-family:’Obliqua ITC W01 Bold’;
font-family:’ObliquaITCW01-BoldItali’;

(We’ll work out how to best use this in just a bit)

Finally, you should have a look at this sample code page showcasing the code required to use the WebFont Loader with Fonts.com Web Fonts. While what is presented there will certainly work, my preference is to keep all JavaScript ensconced in the ‘<head>’ section of the page, and it all seems to work there just swimmingly, like so:

<html>
<head>

<link href=”style.css” type=”text/css” rel=”stylesheet”><!– Our CSS file –>
<script type=”text/javascript” src=”http://ajax.googleapis.com/ajax/libs/webfont/1.0.21/webfont.js” ></script>
<!– Loads the webfont loader –>

<script type=”text/javascript”>
     WebFont.load({
        monotype: {
          projectId: ‘fcd5b553-f7b9-4b45-9093-4e202e2538dd’
           // replace this with your Fonts.com Web Fonts projectId – don’t forget to          do so below as well
        }
     });
</script>

<noscript>

<!– Use this in as a fallback to no JavaScript being available –>
   <link href=”http://fast.fonts.com/cssapi/fcd5b553-f7b9-4b45-9093-4e202e2538dd.css” rel=”stylesheet” type=”text/css” />
</noscript>
</head>

With that we’ve done several things: we’ve embedded the code to trigger the WebFont Loader, given it your Fonts.com Web Fonts project ID to load, and included the aforementioned clever little bit of ‘<noscript>’ code to load the fonts via CSS should JavaScript not be available. That’s actually all that’s necessary in the page itself. Not so bad, right? Our sample page does have some extra bits in it but those are there to allow us to experiment without CSS and see just how it will look in action. The rest is all in our CSS file. (Well, except for the bits we’ve added for our demo that allow us to turn Web fonts on and off, which is invaluable when you want to ‘tune up’ your fallback fonts. But more on that later.)

Before we dive in to that CSS though, let’s take a moment to more clearly explain why we’re taking the trouble to go through this exercise. Without trying to be flip, it’s important to point out that fonts differ from each other in more ways than simple appearance. Spacing can vary widely, which is why I recommend selecting fallback fonts that more closely match the horizontal scale of your chosen web fonts as much as possible. (For example, the Helvetica® and Verdana® typefaces vary greatly in width.)

Sample Text:

Font comparison

The problem you’ll find is that while the Web fonts are loading, either no text will display at all or it will show in the fallback font and probably reflow your text quite a bit. This is exaggerated further when the Web font selected is drastically different in size. This will cause a jarring redraw of the page once the web font loads fully and the browser updates the user’s window with the re-rendered page. By using Font Events to introduce new CSS written specifically to address the display of the fallback fonts we can adjust with the CSS letter-spacing and font-size declarations to minimize or even eliminate the reflow of text on the page. There is also the nascent declaration of ‘font-size-adjust’ but it’s very unevenly implemented as of yet. (Great exploration of that here: http://webdesignernotebook.com/css/the-little-known-font-size-adjust-css3-property/)

Demonstration Page, Fonts Not Loaded (with no CSS correction in place):

Web fonts off, uncorrected

Since we have added Font Events, we can now dive into our CSS. We’ll start with the basic styles for text on the page based on how we want the page to render with our selected Web fonts:

body, caption, th, td, input, textarea, legend, fieldset {
   font-family:”Obliqua ITC W01″, Helvetica, “Lucida Sans”, “Lucida Grande”,   “Lucida Sans Unicode”, sans-serif;
   font-size: 1em;
   letter-spacing: normal;
   line-height: 1.4em;
}

This will be the base, and is applied either once the Font Event ‘loading’ classes are removed or when JS is disabled and the fonts are loaded via CSS instead. However – we want to leverage the Font Events when possible, so we then list this alternate style that is called once the WebFont Loader has inserted the class indicating that Web fonts are loading but not yet active (‘wf-inactive’):

.wf-inactive body,
.wf-inactive caption,
.wf-inactive th,
.wf-inactive td,
.wf-inactive input,
.wf-inactive textarea,
.wf-inactive legend,
.wf-inactive fieldset {
   font-family: Helvetica, “Lucida Sans”, “Lucida Grande”,   “Lucida Sans Unicode”, sans-serif;
   font-size: 1em;
   letter-spacing: -0.015em;
   line-height: 1.4em;
}

Notice a few key things between the first set of declarations and the second: when ‘wf-inactive’ is added, we set the fonts without the Web font listed and adjust the letter-spacing. We could also alter the font-size and increase the line-height at this point. These adjustments were easy to make with our demo page because we’ve added a toggle link to turn the Web fonts on and off. If you give our demo page a look and try it out, you’ll see that it’s quite close – but likely not exact in our goal of ‘no reflow in any browser.’ You may be shocked to hear this, but apparently a pixel is not quite a pixel when it comes to implementing letter-spacing – despite it having been around since CSS1. I know, hard to believe. So we have to fiddle with the fallback values of the second block and test it out in a number of browsers until we are close enough. Mark it down along with horseshoes as one of the few places where ‘close enough’ still scores you points. I’ve done the same in our demo with H1, H2 and H3 headers as examples, but you’ll have to adapt this to your own workflow an CSS in order to ensure that you’ve covered all your bases. Then test, test test! You’ll find that some browsers render letter-spacing smaller, some larger.

Demonstration Page, Fonts Not Loaded (but with CSS correction in place): (image)

Web fonts off, corrected

While one could argue that in order to properly address the page from a progressive enhancement point of view you should actually have your base CSS be the ‘fallback-tuned’ version, but since with Fonts.com Web Fonts you can address the lack of JS with CSS-only embedding wrapped in a standard ‘<noscript>’ block, I would say that this is indeed the proper base writeup, and since it relies upon JS to enable the Font Event classes at all, that the ‘fallback-corrected’ CSS would actually be the ‘enhanced’ bits and therefore should be added only when the Font Events are actually present.

So to put this in practice yourself, follow the samples above and while you’re developing your HTML and CSS, include the handy toggle code from the demo so you can test your adjustments, and simply remove it when you’re done. If you’re developing in Drupal you could even add the toggle as a block with all the necessary code and simply turn it on whenever you need it. The entire demo is available to download – just substitute your own project ID and fonts to give it a try. It’s not too hard, and the benefits will be noticed (or better yet – not noticed) with every page load. Tune away!

View the Demo (tuned the closest in FF, but works in all the browsers I’ve tested)

Experiment on your own! Download the fallback font demo files.

Great Type Makes Sites Stand Out

Start your free fonts.com web fonts subscription today

Start Subscription