CSS Font Loading API - Web Fonts Performance - Responsive Web Design, Part 2 (2015)

Responsive Web Design, Part 2 (2015)

Web Fonts Performance

CSS Font Loading API

The CSS Font Loading Module10 defines a new interface for managing the web fonts in your document. The interface lets you load fonts on demand and gives you JavaScript events for various load states. The module introduces a new FontFace object to represent @font-face rules. It can be used to programmatically create new web fonts or modify existing ones, and serves as a complement to the CSS font-rendering proposal.

You can create a new instance by calling the FontFace constructor with three arguments: the first argument is the font family name, the second is either a string or a typed array, and the third argument is an object describing the web font.

var myfont = new FontFace('My Font', 'url(myfont.woff)'

The string format used for the second parameter is the same as the @font-face src property, so it to supports multiple font formats. Use the third parameter to give the web font various properties such as weight, style and which Unicode characters it supports.

var myfont = new FontFace(

'My Font',

'url(myfont.woff) format("woff"),' +

'url(myfont.otf) format("otf")',

{ weight: 'bold', unicodeRange: 'U+0-7ff' }

);

This creates a new FontFace instance, but it does not load. To load the web font, call the load method on the FontFace instance. This method returns a promise11 which will be fulfilled when the font has loaded, or rejected if it fails to load.

myfont.load().then(function () {

console.log('load success');

}),.catch(function () {

console.log('load failure');

});

This makes a network request to download the font from the server or retrieve it from cache, but it does not add it to the document. An element with this web font in its font stack wouldn’t trigger a font load either. The web font is not available to CSS until you add it to a FontFaceSet.

Each document has its own FontFaceSet that contains FontFace objects for all the @font-face rules in that document. You can use this set to add or remove fonts from the document. The set also contains some methods to explicitly load fonts or to check if fonts are in the set. The set for the current document is available as the fonts property on the document context.

> document.fonts

< FontFaceSet { size: 2, status: "loaded", … }

This set already contains two FontFace objects that are loaded. These could have been @font-face rules in the document’s style sheets, or FontFace objects explicitly loaded by some other script.

We can make our font available by adding it to the set.

document.fonts.add(myfont);

This does not necessarily make the font available right away. The font is only swapped in if it is used in a CSS selector (that matches a DOM node), or if it is explicitly loaded using the set’s load method. If the document contained a CSS selector that referenced this font — and the font was preloaded — it would replace the fallback font right away. If the font wasn’t loaded, browsers would download the font first and then use it to replace the fallback font.

p {

font-family: My Font, sans-serif;

}

It is also possible to explicitly make the font available without having a font stack trigger the loading by using the set’s load method. This function will make the font available whether it is preloaded or not. A font being available means that, even though, the font might not be used in the page, it is ready to be swapped in. The load method takes a CSS font shorthand property value as input.

document.fonts.load('16px My Font');

This will load My Font and make it available. If there is an element in the page that uses “My Font” in its font stack, its fallback font will be replaced with “My Font” immediately. If there isn’t, nothing will happen. Reusing the font shorthand property value offers a convenient method of loading several fonts that match the variation and font family names used in the shorthand.

document.fonts.load('bold 16px My Font, My Other Font');

This will load the bold variation of both “My Font” and “My Other Font” (if they match a @font-face rule). An unfortunate side effect of reusing the font shorthand property is that you are required to specify a font size. The font size is only used to make the shorthand font value syntax legal, but it isn’t used for font matching.

Like the load method on FontFace, the set’s load method also returns a promise which you can use to be notified when the fonts in the set are loaded (or fail to load).

document.fonts.load('16px My Font').then(function () {

console.log('My Font has loaded and is applied.');

});

If you want to check the availability of a font without triggering a load, you can do so using the check method.

document.fonts.check('16px My Font').then(function () {

console.log('My Font is available');

});

The CSS Font Loading API is still under development, but you can already use it in the latest versions of Chrome, Opera and Firefox (behind a flag). If you are targeting modern browsers, you can use a polyfill12 I’ve written for the CSS Font Loading API. The polyfill supports Internet Explorer 9 and later, Firefox, Safari, Android, and iOS. Included with the polyfill is a small promise library, so it is possible to use the polyfill to implement all the examples from this chapter.

If you need support for older browsers, you can achieve the same results using the Web Font Loader13. The Web Font Loader is a collaboration between Typekit and Google, and it gives you the ability to load custom fonts, as well as fonts from several web font services. It also provides font load events so you can use custom styles or scripts when a font loads (or fails to load).