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 specific size intervals. This makes it hard to set a catch-all size on the web and have it work beautifully with many typefaces.
As you can see from the image above, 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 in CSS 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 fallback 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.
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.
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.
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>
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'],
},
});
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.
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
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(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
/* */
/* Ubuntu is defined */
/* */
@import url(https://fonts.googleapis.com/css?family=Ubuntu:400,700,400italic,700italic);
/* */