Tomer Aberbach

Avoid Layout Shifts Caused by Web Fonts With PostCSS Fontpie

Published ·

When your CSS references a web font before it finishes downloading, the browser renders text using a fallback system font instead, causing a layout shift if the text container’s height changes once it’s rendered with the web font.

Optimizing your font files and using an intelligent font loading strategy can eliminate layout shifts, but only if the web font is not immediately used on the page. Otherwise you have to ensure the text container’s height doesn’t change. Fontpie can help with this. It’s a tool for generating CSS that adjusts a fallback font’s metrics so it takes up the same amount of space as your web font. The result is no layout shifts even if the font is immediately used!

Part of what makes Fontpie great is that it’s framework agnostic, but that also means it’s a bit manual to use and I wanted something I could easily integrate into this website’s build. I was already using PostCSS so I decided to make a Fontpie PostCSS plugin. The result is postcss-fontpie. And now generating fallback font metrics for my web fonts is as easy as adding the following to my PostCSS config:

postcss.config.js
const { join } = require(`path`)

module.exports = {
  plugins: [
    // ...
    require(`postcss-fontpie`)({
      fontTypes: {
        dm: `mono`,
        'Kantumruy Pro': `sans-serif`,
      },
      srcUrlToFilename: url => join(__dirname, `src/styles`, url),
    }),
    // ...
  ],
}

You can see the generated fallback font metrics in this website’s CSS and their effects in the following before-and-after GIFs:

Check out postcss-fontpie’s usage example to use it in your own website!