Heya, Thanks for visiting!
edited

Font legibility, crispness(aliasing), and physical size vary between fonts when set at the same font-size. Fonts are designed/optimized at distinct sizes and alias extremely well at those definite size intervals. This makes it hard to set a catch-all size and have it work beautifully with many typefaces.

Font chart

As you can see Calibri is a much smaller font compared to Ubuntu and Open Sans. You can also see the varying levels of clarity between the sizes of each font.

So what if you have a font stack that looks like font-family: 'Ubuntu', 'Calibri', sans-serif; and you fallback to Calibri. All of a sudden your sites font size greatly decreases. Of course Calibri is a great looking font and you want to use it as a fall back but increase the size when it does. This guide will go over how you can have the best of all typefaces and style them just right so the fallbacks are perfect.

CSS only alternative (maybe)

The font-size-adjust property takes a stab at this issue by making font size actually based on the size of the lower case letters in the loaded font. It works as a scalar for font-size and guarantees the font will be scaled so that the lowercase letter height will be font-size*font-size-adjust. In the example snippet below the typefaces lowercase letter height would be 6px.

/* lower case letters will be 6px high */
font-size: 12px;  
font-size-adjust: 0.5;

This helps with legibility at small sizes between font fallbacks but still does not let you customize the size based on the font family. Another problem is that font-size-adjust is only supported in Firefox at the moment.

Introducing Web Font Loader

To achieve the true font-size based on font-family we are going to be using Adobe Typekits Web Font Loader JavaScript library. The readme in the GitHub repo explains a lot and goes through many configurations but I will be going over just what we need to get font-size based on font-family.

Web font Loader works by identifying if the fonts specified in the modules of the configuration are loaded. And then adding corresponding css classes(what Typekit calls Events) to the HTML tag of your page. You can then use those classes in your CSS to style your page appropriately.

Don't be confused by the name "Web Font Loader", as we are not using the library to load/import fonts into the page(in this guide). We are simply testing for whether they are already loaded and are able to be used in the page.


How to use Web Font Loader

Web Font Loader(webfont.js) is a google hosted library so it is easy to include and use. You could always download and include it yourself. Web Font Loader even works offline(for the features we are using in this guide).

// Link the latest 1.x version. This applies to any google hosted library.
<script src="//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js"></script>
// Or specify a set version
<script src="//ajax.googleapis.com/ajax/libs/webfont/1.5.3/webfont.js"></script>

Initialize the library

There are two ways to run Web Font Loader, but the easiest and most sensible way to me is to just call WebFont.load({}). The other way is to set the global variable WebFontConfig and then include the webfont.js library. If you are using JS strict mode "use strict";, then use window.WebFontConfig = {}; to keep from getting errors.

After you have webfont.js included somewhere; Add each font family you are using to the custom module families array. In this small example we are going to use Open Sans which looks good at a base size of 12px and Ubuntu which looks good at a base size of 13px.

You can put this snippet in a <script> tag at the bottom of the body so that it runs once the page has been fully parsed and rendered. It will work just fine if you include it in the head(or wherever).

// Get classes from fonts
WebFont.load({
    custom: {
        families: ['Open Sans', 'Ubuntu']
    }
});

Define Font Sizes using the Event Classes

Once the snippet above executes, it will add the css event classes the HTML element of the page. We can use the CSS event classes to set a font-size for each family.

Web Font Loader Even Classes

The syntax for the CSS events looks like this:

.wf-<familyname>-<fvd>-active

<familyname>: Lowercase name of the font. Spaces and underscore are stripped out.
<fvd>: Shortand for describing the weight and style. ex.

  • n4: normal style, weight: 400 (normal)
  • n7: normal style, weight: 700 (bold)
  • i4: italic style, weight 400 (normal)

We will just be using the n4 fvd variant as there is no need to test each flavor of the font.

Define the event classes in opposite(left->right to bottom->top; see example below) order you have in the font-family stack on your body. This way they will override each other correctly when you have to fallback.

body {
    font-family: 'Open Sans', 'Ubuntu', sans-serif;
    font-size: 12px;
    font-weight: 400;
}
/* Change font-size based on font-family 
 * We get these event classes from the webfontloader
*/
.wf-ubuntu-n4-active body {
    font-size: 13px;
}
.wf-opensans-n4-active body {
    font-size: 12px;
}

Now when Open Sans is available, it will use a font-size of 12px.
If Open Sans is not available and the font-family stack falls back to Ubuntu, it uses a font-size of 13px

Demo: jsFiddle

You can check out a demo of what the guide goes through.

To test the font fallback and size change, just put a space between the multi-line comment like so /* * / for the @import definitions in the CSS. This will toggle the import on and off. If you already have Open Sans or Ubuntu installed locally in your OS, you won't see the difference.

/* Open sans is commented out (notice the space) */
/* * /
@import url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
/* */
/* Ubuntu is defined */
/* */
@import url(http://fonts.googleapis.com/css?family=Ubuntu:400,700,400italic,700italic);
/* */