font-display

Avatar of Geoff Graham
Geoff Graham on (Updated on )

📣 Freelancers, Developers, and Part-Time Agency Owners: Kickstart Your Own Digital Agency with UACADEMY Launch by UGURUS 📣

The font-display property defines how font files are loaded and displayed by the browser. It is applied to the @font-face rule which defines custom fonts in a stylesheet.

@font-face {
  font-family: 'MyWebFont'; /* Define the custom font name */
  src:  url('myfont.woff2') format('woff2'),
        url('myfont.woff') format('woff'); /* Define where the font can be downloaded */
  font-display: fallback; /* Define how the browser behaves during download */
}

Values

The font-display property accepts five values:

  • auto (default): Allows the browser to use its default method for loading, which is most often similar to the block value.
  • block: Instructs the browser to briefly hide the text until the font has fully downloaded. More accurately, the browser draws the text with an invisible placeholder then swaps it with the custom font face as soon as it loads. This is also known as a “flash of invisible text” or FOIT.
  • swap: Instructs the browser to use the fallback font to display the text until the custom font has fully downloaded. This is also known as a “flash of unstyled text” or FOUT.
  • fallback: Acts as a compromise between the auto and swap values. The browser will hide the text for about 100ms and, if the font has not yet been downloaded, will use the fallback text. It will swap to the new font after it is downloaded, but only during a short swap period (probably 3 seconds).
  • optional: Like fallback, this value tells the browser to initially hide the text, then transition to a fallback font until the custom font is available to use. However, this value also allows the browser to determine whether the custom font is even used at all, using the user’s connection speed as a determining factor where slower connections are less likely to receive the custom font.

Here’s another way to think about them

 Block PeriodSwap Period
blockShortInfinite
swapNoneInfinite
fallbackExtremely ShortShort
optionalExtremely ShortNone

Why We Need font-display

Before we had widespread support for @font-face, our typographic arsenal was limited to local fonts, where the only available fonts were the ones that came preloaded on the end user’s computer. We call these “web safe” fonts because the browser does not need to download anything in order for them to be rendered.

Then came the @font-face rule which gave web designers and front-end developers new typographical powers unlike ever before. It allowed us to upload font files to a server and write a set of rules in our stylesheets that name the font and tell the browser where to download the files. It also gave rise to services like Google Fonts which brought custom fonts to the masses. Finally, a major hurdle that separated web design from print design had been toppled!

However, custom fonts came (and continue to come) at a cost. Font files can be large and the extra time to download the files can slow the performance of a site, particularly for devices on a slower network connection. The extra cost to users on limited data plans also became a factor.

One other particular concern that arose with custom fonts is what was dubbed a “flash of unstyled text” or FOUT for short. Browsers would default to showing a system font while waiting for the custom font to download. This allowed web pages to load faster but raised concerns among web designers who viewed this as hijacking the user experience and misrepresenting the intended design. Web browsers today generally hide the text until the custom font is downloaded, which we now refer to as a “flash of invisible text” or FOIT.

Neither FOUT nor FOIT is great. We have ways to optimize the performance of custom fonts to help ease the effects. However, now we have font-display to tell the browser whether we prefer FOUT, FOIT, or even something in between.

Testing for Support

Interesting caveat noted by Šime Vidas:

CSS font-display is a @font-face descriptor and not a property, so its support in the browser cannot be tested with feature queries (CSS @supports rule and CSS.supports API).

More Information

Browser Support

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeFirefoxIEEdgeSafari
6058No7911.1

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
12212312211.3-11.4