The Publishing Project

Overriding Font Metrics with CSS

One of the things about web fonts that may be problematic is the care we need to take when choosing a fallback font. Unless we pick fonts with similar characteristics, there will be a layout shift that will negatively impact the LCS core web vitals metric.

CSS has a potential solution to this problem. In CSS we can use special override descriptors in the @font-face at-rule to specify the exact dimensions for the following attributes:

The example @font-face declaration below shows how these descriptors work.

@import url('https://fonts.googleapis.com/css2?family=Playfair+Display&display=swap');

@font-face {
  font-family: "Times New Roman";
  /* These values are based on Fair Play's table data */
  ascent-override: calc(138.496 / 128 * 100%);
  descent-override: calc(32.128 / 128 * 100%);
  line-gap-override: 0%;  
  advance-override: 0.049;
  src: local("Times New Roman");
}

For each of the new descriptors, we provide a value we’ve calculated from the web font we’re downloading so that the fallback font, Times New Roman, will use the same dimensions and reduce or eliminate layout shift because of font metric differences

Proposed Descriptors

These are the descriptors implemented in Chrome and being discussed in the CSS working group

ascent-override, descent-override, line-gap-override

  • Syntax: <percentage> | normal
  • Initial value: normal

These descriptors allow us to completely eliminate the vertical layout shift.

Having these values enables browsers to match fallback font metrics to those of the web font they are replacing, reducing layout shift.

It is important to remember that the values for these descriptors are used in the fallback local font but use the values from the web font being replaced

advance-override

  • Syntax: <number>
  • Initial value: 0

This descriptor allows us to reduce the horizontal layout shift and helps to reduce vertical layout shift caused by different line-wrapping.

The descriptor sets an extra advance for each character using the font face. The amount of extra advance equals the descriptor value multiplied by the used font size.

Some remaining questions

The values of these descriptors should be set according to the head and hhea table of the target web font.

Because of this, it’s hard to use the overrides well. We need a way to pull this data from the web font file without having to code it ourselves, maybe with tools like wakamaifondue or the browser’s DevTools (Firefox does an awesome job with their DevTools font editor already).

I filed an issue in the Wakamai Fondue Github repository asking for the application to provide these metrics for you.

Links and References