Loading Web Fonts

Custom fonts within our application load once the CSS evaluation completes, if the browser determines that its actually used on the page. We can ask the browser to start loading them as soon as it discovers the element, using a link with rel="preload".

<link
  rel="preload"
  href="/fonts/Inter-Bold.woff2"
  as="font"
  type="font/woff2"
  crossorigin
/>

We are still not covered

Although now our fonts are being preloaded, they will not load immediately. We have a timespan between the font being requested and the font being loaded, that may vary depending on the size of the fonts, the network speed and more.

During this timespan our text will be displayed with a fallback font or with no font at all depending on the font-display strategy we have defined (more about this in Font Display).

Based on the visual differences between our custom font and the determined fallback font, we may introduce a layout shift (which is an important metric for Google Core Web Vitals) in our application, as seen in the example below:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas convallis mauris dui, non placerat urna fringilla at. Suspendisse a orci quis arcu tristique sagittis at sed leo. Nam quis neque dapibus, semper nisl non, lacinia ligula. Duis viverra a nisl ut consectetur. Ut elementum fringilla odio viverra egestas. Morbi aliquet lorem lorem, in suscipit nibh tempus quis. Mauris gravida dapibus odio, vitae interdum lectus pretium ut. Vivamus tincidunt laoreet pellentesque. Praesent tincidunt elementum tempus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas convallis mauris dui, non placerat urna fringilla at. Suspendisse a orci quis arcu tristique sagittis at sed leo. Nam quis neque dapibus, semper nisl non, lacinia ligula. Duis viverra a nisl ut consectetur. Ut elementum fringilla odio viverra egestas. Morbi aliquet lorem lorem, in suscipit nibh tempus quis. Mauris gravida dapibus odio, vitae interdum lectus pretium ut. Vivamus tincidunt laoreet pellentesque. Praesent tincidunt elementum tempus.

Fonts with different sizes may create a layout shift in its space and may also push or pull content around it creating a bigger shift in the UI.

One possible solution is having an adjusted fallback font that tries to match the used space of our custom font to reduce the layout shift. You can use this tool to find which fallback font might match your custom font and set the correspondant line-height to it so it adjust accordingly.

Here we can see the difference that using an adjusted fallback font makes:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas convallis mauris dui, non placerat urna fringilla at. Suspendisse a orci quis arcu tristique sagittis at sed leo. Nam quis neque dapibus, semper nisl non, lacinia ligula. Duis viverra a nisl ut consectetur. Ut elementum fringilla odio viverra egestas. Morbi aliquet lorem lorem, in suscipit nibh tempus quis. Mauris gravida dapibus odio, vitae interdum lectus pretium ut. Vivamus tincidunt laoreet pellentesque. Praesent tincidunt elementum tempus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas convallis mauris dui, non placerat urna fringilla at. Suspendisse a orci quis arcu tristique sagittis at sed leo. Nam quis neque dapibus, semper nisl non, lacinia ligula. Duis viverra a nisl ut consectetur. Ut elementum fringilla odio viverra egestas. Morbi aliquet lorem lorem, in suscipit nibh tempus quis. Mauris gravida dapibus odio, vitae interdum lectus pretium ut. Vivamus tincidunt laoreet pellentesque. Praesent tincidunt elementum tempus.

Font Display

As we mentioned above, during the timespan between our page displaying text and our custom font being applied to that text, we can choose one of several behaviors that will determine how that text will be displayed, using the font-display CSS property.


font-display: autofont-display: auto: This is the default value of font-display. The text will be invisible while the custom font is loading, the reserved space depends on the space that would have been occupied by the fallback font.

font-display: swapfont-display: swap: The browser will display the text using the fallback font while the custom font loads and then swap the fonts once it has finished loading.

font-display: optional

font-display: optional: The browser will only display the custom font if it is available before it has to start rendering text. If the font is cached it'll be less likely for users to see the fallback font on subsequent visits.

Layout shifts are reduced by using this strategy, as the browser won't swap the fonts after rendering the page with the fallback font.

If you don't add a link with rel="preload" for this font (which triggers a special heuristic) it'll never be shown in the first page load unless it is in memory cache, even if it is in disk cache.

Learn More

If you want to know more about loading web fonts you can refer to this post about font loading by Malte Ubl and also to the MDN documentation font-display.