Happy holiday folks! All the best from us at Digitpaint

Day 11

Being in control of font-display

No more javascript-tricks to detect whether your shiny font has loaded or not! All we need is one line of CSS. In Chrome, Firefox, Opera and Safari (TP), that is …

To see this in action you'll need to clear your cache, simulate a slow network connection in your dev tools, refresh this page and observe how the fonts render in this demo.

Font-display: auto

Font-display: block

Font-display: swap

Font-display: optional

Font-display: fallback

I didn't see it!

For your viewing convenience we have created a little video (using the Chrome profiling tab) to show you how the 5 different font-loading strategies that font-display currently supports work. We've simulated a very slow network connection to make the effects visible.

Font loading in the browser

When a font is loaded in a browser, the text that is styled to use that font is, by default, hidden until the font is loaded. After about 3 seconds, most browsers will use a fallback font to make the text visible, while it's waiting for the actual font to load. Some browsers will wait even longer, and some will wait forever, causing the user to not see the text at all.

This behaviour may prevent the user from seeing text that is not styled, but the downside of this solution is that users with slow network connections have to wait a very long time before any text is rendered.

The workaround

One way to work around this problem, is to make use of javascript and the Font Loading API. A document is initially rendered with system fonts. With JavaScript we can detect if our custom fonts are loaded. If this is the case, a CSS class gets added to the document, which applies the now loaded custom font to the text.

With font-display, we can ditch the JavaScript and control how fonts display with one single line of CSS!

What does font-display bring to the table?

Before we look at the different options of font-display, we first need to understand a bit about the load timeline of a font. The inner workings in the browser are probably much more complex but it basically boils down to the three periods below.

Font loading timeline

The font block period
This starts when the browser starts an attempt to load the font. If the font is not loaded during this period, the text that needs to be styled with this font is rendered with an invisible fallback font. When the font successfully loads during this period, the text will be rendered with the requested font.
Font swap period
The font swap period occurs immediately after the font block period. If the font is not loaded during this period, the text that needs to be styled with this font is rendered with a fallback font. If the font successfully loads during this period, the requested font will replace the fallback font.
Font failure period
The font failure period occurs immediately after the font swap period. If the font is not yet loaded when this period starts, it’s marked as a failed load, causing the browser to use a font fallback.

With the font-display property we can influence the timing of the font block and font swap periods. Luckily we don't have to decide how to time them for ourselves, because they are predefined in the following 5 strategies (which incidentally are also the values you can give the font-display property.

The default strategy. The browser uses its default font loading strategy, which is most often similar to block.
Gives the font face a short block period and an infinite swap period. This value should only be used if rendering text in a particular typeface is required for the page to be useable.
Gives the font face no block period and an infinite swap period. This strategy is similar to the font loading behaviour that we relied on when we were using JavaScript. This value should be used when rendering text in a particular font is important for the page, while rendering in any font will still get the message across.
Gives the font face an extremely small block period and a short swap period. Fallback is especially useful for things like body text where you’d like the user to start reading as soon as possible and don’t want to disturb their experience by shifting text around as a new font loads. The effect of this property is that it will show the user the font on a consecutive page-view as the font is probably cached by then.
Gives the font face an extremely small block period and no swap period. Similar to fallback, this is a good choice for situations in which the downloading font is more of a complementary thing; if it isn't critical to the experience. This can be beneficial in situations where the user is on a weak connection and pulling down a font may not be the best use of resources.

To use the font-display property, add it to the @font-face rule:

@font-face {
  font-family: 'yourfont';
  src: url('yourfont.woff') format('woff');
  font-display: swap;

Browser support

font-display is not yet supported by all major browsers. Since it is a property used in the @font-face rule, it's support can not be tested with feature queries (e.g. @supports). There are 2 ways in which you can use font-display:
  1. Just use font-display anyway. Browsers that don't support it will fall back to their default behaviour.
  2. You can detect support for font-display with JavaScript and provide an alternative.
  • Chrome
  • Firefox 58+
  • Opera
  • Safari Technology Preview
  • Chrome for Android

more detailed information on caniuse.com


Demo source code

Do you want to dig in the nitty-gritty of this demo, check out the source files:

Back to home