Skip to main content
Dublin Library

The Publishing Project

Loading Fonts

 

Now that we have a better idea of what fonts we want to use and the font stack we'll see how to load them into the page. We'll explore 3 ways: local loading using the _@font-face syntax_, loading fonts using the [Google font API](https://developers.google.com/fonts/docs/getting_started), using Google's [Web Font Loader](https://github.com/typekit/webfontloader/blob/master/README.md) and a new tool called [Font Face Observer](https://github.com/bramstein/fontfaceobserver/blob/master/README.md) ### @font-face We have been able to use fonts on our web content since the days of IE 3 (3.5 for Macintosh if I remember correctly) but we've always had to contend with font creators and foundries fear of piracy. It's only recently that they have relented and allowed their fonts to be used. The basic syntax, covering all modern browsers, looks like this: ```css @font-face { font-family: 'stone-sans-webfont'; src: url('../path-to-font-file.eot'); src: url('../path-to-font-file.eot?#iefix') format('embedded-opentype'), url('../path-to-font-file.woff2') format('woff2'), url('../path-to-font-file.woff') format('woff'), url('../path-to-font-file.ttf') format('truetype'), url('../path-to-font-file.svg#stone-sans-webfont') format('svg'); font-weight: normal; font-style: normal; } ``` And then we associate the font with CSS like we normally would matching the font-family attribute in the @font-face declaration with the font-family attribute of the element where we want to use it: ```css html { font-family: 'stone-sans-webfont', arial, sans-serif; } ``` Since we want to avoid faux bold and faux italics in our content, we add the bold and italics versions of our font to the page and then match them to the correct attributes with selectors similar to this: ```css strong { font-family: 'Stone-Humanist-Semi'; } em { font-family: 'Stone-Humanist-Ita'; } /* When using both we don't care what order they are used in */ strong em, em strong { font-family: 'Stone-Humanist-SemiItalic'; } ``` Where _Stone-Humanist-Semi_ is our (semi)bold font, _Stone-Humanist-Ita_ is italics and _Stone-Humanist-SemiItalic_ is the semibold italics combination. Since `` and `` have different semantic meaning in HTML5 I've chosen not to style them. #### Some things to keep in mind Adding the font to your site/book/app adds to the overall file size. Depending on the font this may increase the size of your project considerably. Taking [Gentium](http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=gentium) as an example, the font supports Latin, Greek and Cyrillic character sets but it weighs a hefty 500k for the regular font (in one format out of the 5 formats needed to support multiple browsers/devices). Add Bold, Italic and you get 1.5 Megabytes just for the font! And it may not be the only font you use in the project. The flipside to this issue of size is that embedding the fonts means they are always available to desktop and mobile browsers readers that support embedding (and it should be all of them.) Choosing what browsers and what versions to support is a different story. ### Google Fonts API Google has two ways of using web fonts, the first one is directly through their API. Using Google's font API is a two step process. First add the font to your html head element with the following syntax (using Tangerine as an example): ``` ``` The link produces a CSS @font-face declaration that we can use in our CSS as normal. The version produced in Chrome and Firefox uses the [woff2](http://www.w3.org/TR/WOFF2/) format ```css @font-face { font-family: 'Tangerine'; font-style: normal; font-weight: 400; src: local('Tangerine'), url(http://fonts.gstatic.com/s/tangerine/v6/HGfsyCL5WASpHOFnouG-RJBw1xU1rKptJj_0jans920.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; } ``` While Safari uses True Type to render the font. ```css @font-face { font-family: 'Tangerine'; font-style: normal; font-weight: 400; src: local('Tangerine'), url(http://fonts.gstatic.com/s/tangerine/v6/HGfsyCL5WASpHOFnouG-RCZ2oysoEQEeKwjgmXLRnTc.ttf) format('truetype'); } ``` As you can see the advantage of using the APi is that we don't need to use multiple formats in our @font-face declaration. Google takes care of that for us. The obvoius disadvantage is that this only works online. That's why a fallback option or options is even more important when working with the API. If we're offline or connectivity is limited we want a good fallback font. ### Google web font loader One of the things neither the font API or directly downloading the content doesn't address is the "flash of unstyled text." According to the [Typekit Help Center](http://help.typekit.com/customer/portal/articles/6852-Controlling-the-Flash-of-Unstyled-Text-or-FOUT-using-Font-Events): > Fonts are loaded as assets into a web page—just like images or video. Depending on your browser or your connection speed, they can load quickly or lag behind the rest of the page. Different browsers handle font loading differently; for example, Safari and Chrome will refrain from displaying text set in a web font until the font has loaded, while Internet Explorer won’t show anything on the page until the font loads. Meanwhile, Firefox will display the site with the fallback fonts in the font stack, and then switch to the linked fonts after they’ve finished loading. This results in a flash of unstyled text, or FOUT. Typekit, in collaboration with Google, has created loader library to make working with type easier. It works by adding scripts to the page that load the library and tell it what fonts to download and use. For example to load the Droid Sans font from Google you'd use code like this: ```markup ``` Or using asynchronous loading: ```javascript
``` The first thing we do is to use Server Side Includes, a way to have the server generate pieces of content for the web, to add the `fonts-loaded` CSS class if the corresponding cookie has already been set. In this way the loader will only use the fonts if they've been already been loaded, otherwise it will not add the class and the process will continue. ```markup ``` While still in the head of the document we load our fonts using the @font-face syntax we discussed earlier and associate the fonts with the css needed. Note that we have two classes for the body, a plain one where only system fonts are used and a version with the fonts-loaded class where the webfont is the primary and the system font is our backup. ```markup ``` At the bottom of our pages, along with all the other scripts, we add a link to the fontfaceobserver library. The second script begins with a conditional check to see if the `class-loaded` class hs been added to the root element (html); if it has been then quit, there is nothing left to do. We next define variables for each of the fonts we will use in our document. This will be used in the last part of the script, discussed below. ```markup ``` The next result is that the fonts will be loaded asynchronously and that the system font assigned to an element will only change after the font has loaded. This prevents flashes of unstyled content and flashes of invisible content. But in the end which font loading strategy you use is up to you. ### Links and Resources - [Delivering Web Fonts](https://prowebtype.com/delivering-web-fonts/#observer) chapter from Professional Web Typography - [Font Loading Revisited with Font Events](http://www.filamentgroup.com/lab/font-events.html) - SSI instructions for [Apache HTTPD](http://httpd.apache.org/docs/current/howto/ssi.html) - SSI instructions for [Nginx](http://nginx.org/en/docs/http/ngx_http_ssi_module.html)

Edit on Github