Recently Updated: 16 min read

Font CLS Fix: font-display, Fallback Metrics, Preload

Font CLS Fix: font-display, Fallback Metrics, Preload

If your headline jumps a few pixels the moment a web font arrives, you have a font-driven layout shift, and it counts toward Cumulative Layout Shift. The short answer: load the font early, choose a font-display value that matches the job of the text, and make the fallback font occupy nearly the same space as the real one. This guide walks through each step with decision rules and a testing routine. It is a technical how-to, not a promise of any ranking outcome.

It is written for site owners who changed a theme font and noticed the page twitch, for SEO specialists who need to brief a developer precisely, and for developers who found a CLS warning and want to know whether fonts are the cause. For the wider measurement picture, see the page speed and Core Web Vitals guide; here we stay with typography.

Why a Font Swap Moves the Page

A browser starts painting before it has your custom font. It must either wait with invisible text or show the text in something else. Both choices touch the layout.

Two behaviors, one problem

The first behavior is a flash of unstyled text (FOUT): text appears in the fallback font and is redrawn when the web font arrives. The second is a flash of invisible text (FOIT): the text is hidden until the font is ready. The web.dev guide to optimizing CLS (Opens in a new tab) states that both approaches can cause layout shifts.

People often assume the invisible version is safe. It is not, because invisible text still takes up room. The guide puts it plainly: even if the text is invisible, it is still laid out using the fallback font. When the real font lands, glyph widths change, lines wrap differently, line boxes grow or shrink, and everything below the text moves.

What decides how far things move

Three variables set the size of the jump:

  • The difference in average glyph width between the fallback and the real font. Wider glyphs mean more line breaks.
  • The vertical metrics, meaning ascent, descent and line gap. Two fonts at the same size can still produce different line box heights.
  • The place the text occupies. A hero headline or the first screen of body copy matters far more than a footer link.

Icon fonts are a special case. The font guidance notes that their fallbacks often look very different and can even convey a different meaning, so they cause larger shifts. Replacing them with SVG, where you can, fixes the shift and helps accessibility at the same time.

The thresholds to keep in mind

The CLS article treats a score of 0.1 or less as good and anything above 0.25 as poor, with the range between needing improvement. It suggests aiming for 0.1 or less for at least 75 percent of page visits. Fonts rarely produce the whole score on their own. They add to image, embed and ad-slot shifts, so measure them as a separate line item, otherwise you cannot tell what is left to fix.

Example scenario: a product page with a branded heading

Imagine a product page where the heading is set in a branded display font and the description in a system font. On a slow first visit the heading arrives late. The fallback heading fits on one line, the real heading needs two, and the price, the buy button and the gallery all move down. The visitor, who was about to tap a size option, taps the wrong thing. Nothing was wrong with the font file; the fallback and the real font simply occupied different amounts of space.

Choosing a font-display Strategy

The font-display descriptor tells the browser what to do while a font is loading. It describes two windows: a block period, during which text is invisible, and a swap period, during which a fallback is shown and replaced if the font arrives. Without it, the font best practices page (Opens in a new tab) says, Chromium and Firefox block text for up to 3 seconds while a web font loads and Safari blocks indefinitely.

How each value behaves

ValueBlock periodSwap periodShift risk
------------
autoBrowser decidesBrowser decidesUnpredictable
block2 to 3 secondsInfiniteYes, though text is hidden first
swap0 msInfiniteYes, whenever the font arrives
fallback100 ms3 secondsOnly if the font arrives in time
optional100 msNoneNo, a late font is never applied

A decision rule you can hand to a team

The guidance translates into four plain rules:

  1. If stability and speed come first, use optional. Text is delayed by at most 100 ms and no font-swap shift happens. If the font is late, the page keeps the fallback.
  2. If the text must appear immediately and the web font should still be used, choose swap, but deliver the font early enough that a visible swap is rare.
  3. If the text must appear in the web font, choose block and deliver the font early to keep the delay short. A shift can still occur, though the guidance notes it may be less jarring than with swap.
  4. Mixing is allowed. Swap for brand and distinctive elements, optional for body text.

If you need one default, make it optional for body copy and reserve swap for the few elements where the brand font is the point.

The price of optional, and how preload pays it

The cost of optional is real: when the font misses the first paint, that page view never uses it. A first-time visitor may never see your brand font. Preloading is the usual remedy. The web.dev article on preloading optional fonts (Opens in a new tab) calls preload plus optional the most effective way to guarantee no layout jank when rendering custom fonts. It describes how, from Chrome 83, a preloaded optional font makes the browser skip the first render cycle and wait until the font loads or a timeout passes. The article gives the timeout as 100 ms and says it may change. If the font misses it, the fallback is used and nothing swaps later.

Do not forget the generic family

Whatever value you pick, end every font-family list with a generic family such as sans-serif or serif. According to the CLS article, without one Chrome falls back to its default serif font, which is a worse match for most text than a deliberate sans-serif fallback.

Fallback Fonts That Behave Like the Real Thing

Loading earlier shrinks the problem but does not remove it, especially on a cold first visit. The remaining lever is the fallback itself. The CLS article names four descriptors for this: size-adjust, ascent-override, descent-override and line-gap-override. They adjust the fallback font, not the web font.

What each descriptor controls

  • size-adjust scales the glyphs of the fallback up or down so that its average character width approaches the web font's.
  • ascent-override sets the height above the baseline used for the line box.
  • descent-override sets the height below the baseline.
  • line-gap-override sets the extra spacing between lines.

You define them inside an @font-face rule that points at a local system font with local() and gives it an alias, for example a name like "Brand Fallback". In your font-family list you then write the web font first, the alias second and the generic family last.

The arithmetic

The Chrome article on improved font fallbacks (Opens in a new tab) gives the formulas. With metric overrides only, ascent-override equals the font's ascent divided by its units per em (UPM), and descent and line gap work the same way. When size-adjust is also used:

  • size-adjust equals the web font's average character width divided by the fallback's average character width.
  • ascent-override equals ascent divided by the product of UPM and size-adjust, and the same for descent and line gap.

The percentages go into the descriptors. The article is honest about a limit: average character width can only be approximated. It suggests a letter-frequency-weighted average over lowercase letters and the space for English, or the xAvgCharWidth value with caveats. If your copy is not English, measure a representative paragraph of your own text in both fonts rather than trusting an English-weighted figure.

Which local fonts make sense

The article recommends Arial as a sans-serif fallback and Times New Roman as a serif fallback, noting that neither exists on Android, where Roboto is the only system font. Windows-only names such as Calibri only make sense when you know the visitor's operating system. A common arrangement for a sans-serif brand font is therefore two fallback definitions, one based on Arial and one on Roboto, so both desktop and Android visitors are covered.

Cautions that save an afternoon

Three details deserve attention. First, recompute the values for your own font instead of pasting ready-made sample numbers. Second, it advises against trying to replace this technique with line-height. Third, browsers read vertical metrics from different font tables depending on platform, for instance hhea on Mac and typo or win on Windows for Chromium, so a match that looks perfect on one machine can differ slightly on another. The article says that for about 90 percent of Google Fonts a single set of overrides works across operating systems; confirm that for your own font before relying on it.

For framework users there are packages that generate these values automatically, and the article lists tools for reading metrics: fontkit, Capsize, fontdrop.info and FontForge.

When the effort is worth it

Matching metrics costs time. It pays off when you use swap, when the web font carries the first-screen heading or body copy, and when your measurement still shows font-related shift. If a font is both optional and preloaded, most visits will not need the fallback tuning at all, but it remains a safety net for the visit where the file is slow and uncached.

Getting Font Files to the Browser Sooner

A font that arrives sooner shifts less, or not at all. The best-practices page opens its loading advice with the same instruction: load fonts as early as possible.

What actually triggers a download

An @font-face declaration does not start a download by itself. The file is fetched only when styles on the page use that font. So anything that changes when your CSS is discovered also changes when the font is requested, and removing unused CSS can reduce how many fonts are loaded at all. The guidance recommends inlining font declarations and critical CSS in the document head for most sites, but not the font files themselves, because large inlined resources delay the main document. It adds that if only part of the CSS is inlined, the browser still waits for all of it before it discovers the fonts it needs.

Preload, with limits

Preload makes a font discoverable early, and it has three caveats on that page: it takes browser resources from other resources, it ignores unicode-range declarations, and it should be used for a single font format. The page positions inlining declarations and adjusting stylesheets as the root-cause fix, with preload most useful for the most important fonts that are referenced from external stylesheets. A good working limit is one or two files, the ones used above the fold.

Third-party font hosts

When fonts come from another origin you pay for a connection first. The guidance recommends a preconnect for the stylesheet origin and a separate preconnect with the crossorigin attribute for the font file origin, since font files require CORS. For Google Fonts those origins are fonts.googleapis.com and fonts.gstatic.com, the latter with crossorigin. It also prefers the link form of the Google Fonts embed over a CSS import, because the link version includes a preconnect hint and likely delivers the stylesheet faster.

Self-hosting is not automatically faster

The page cites Web Almanac data showing cases where third-party fonts rendered faster, and says self-hosting is more likely to help only if the site uses a CDN and HTTP/2. Compare transfer time, including connection setup, for the same font from both sources before deciding. If you self-host, you inherit the optimizations that providers normally do for you, namely WOFF2 compression and subsetting.

File format and subsetting

WOFF2 is described as the newest format with the widest support and best compression; it uses Brotli and compresses about 30 percent better than WOFF. The unicode-range descriptor lists the characters a font file covers, and the browser downloads the file only when the page contains matching characters. Latin fonts typically hold roughly 100 to 1,000 glyphs, while CJK fonts can exceed 10,000. Google Fonts subsets by default; self-hosters often forget and end up with larger files. If your site is multilingual, check that each subset includes the accented letters of every language you publish, because a missing glyph is drawn from another font and can shift a single line. Also confirm that the font license allows subsetting and self-hosting.

Fewer fonts, fewer problems

System fonts need no download and work well for body text, though they look different on each operating system. Variable fonts can replace several static files for light, regular, bold and extra bold, but they are usually larger than a single-style file, so they help when you actually use many weights and styles. For a design that only uses two weights, a variable font may make the payload bigger. When you choose type for long articles, the readable content formatting guide covers the reading side of the decision.

Proving the Fix

Do not declare victory from a single fast reload on a developer laptop. Font problems show up on cold caches and slow networks.

The quick lab loop

In Chrome DevTools, the Timing tab of the Network panel shows when fonts arrive. The Performance panel marks layout shifts and the elements that moved. Throttle the network and disable the cache, then reload. To test a fallback match, compare the page with the web font blocked and with it loaded: if the line breaks and the position of the content below are the same, the match is good.

Confirming with real-user data

A lab run is one device on one simulated network. Real visitors vary widely in how late a font arrives. Read the outcome the way the CrUX field data versus lab data guide explains: field data is a 28-day rolling window, so a fix shows up gradually, and one day's movement is not a verdict. Check mobile separately, using the mobile-first indexing checklist as a companion.

Ongoing care

Font fixes decay. A theme update, an extra weight, a new heading style or a font host changing a file path can quietly undo them. Three habits help:

  1. Keep font declarations and fallback values in one stylesheet so you can see which weights are requested.
  2. After every design change, run one pass with a throttled network, an empty cache and a phone-sized viewport.
  3. Recalculate fallback values whenever the web font changes. A new font has new widths and metrics, and old values would correct in the wrong direction.

Give one person ownership of this check, otherwise it becomes an unowned performance chore.

Pre-release checklist

  • Was a font-display value chosen deliberately for body text, with optional as the default?
  • Does every font-family list end with a generic family?
  • Are at most one or two above-the-fold font files preloaded, with the crossorigin attribute?
  • Are fonts served as WOFF2 and subsetted with unicode-range when appropriate?
  • Do the subsets cover every accented letter used on the site?
  • Do third-party font hosts have two preconnect hints, one with crossorigin?
  • Could icon fonts be replaced with SVG?
  • Were size-adjust, ascent, descent and line-gap values calculated from the formula and checked in a browser?
  • Were line breaks compared on a slow network before and after the font loaded?
  • Was font-related shift measured as its own line item?

Symptom to action table

SymptomLikely causeFirst action
---------
Heading pushes content down when it appearsFallback and web font widths differTune size-adjust and the vertical overrides
Brand font never shows on first visitoptional with a late fontPreload it and trim the file
Text is invisible for secondsblock or default behaviorSwitch to swap or optional
Font files are heavyNo subsettingWOFF2 and unicode-range
Icons turn into different symbols brieflyIcon font fallbackMove to SVG

Frequently Asked Questions

Does font-display swap remove layout shift?

No. Swap shows text at once, but when the web font replaces the fallback the layout can shift if their metrics differ. The best-practices page says swap delays text rendering the least among the options that can cause shifts, not that it prevents them. Pair it with early delivery and a metric-matched fallback.

When is font-display optional the right choice?

When performance and layout stability matter most, especially for body text. Text is delayed by at most 100 ms and the late font never causes a re-layout. The trade-off is that a font arriving after the first paint is not used on that page view. Preloading raises the chance that it arrives in time.

How do I work out fallback metrics?

Divide the web font's average character width by the fallback's to get size-adjust. For each of ascent, descent and line gap, divide the value by the product of UPM and size-adjust. Read the font's metrics with a tool such as Capsize, fontkit or fontdrop.info, and verify the result in a browser.

Is preloading a font always a good idea?

No. It makes the font discoverable earlier but takes resources from other requests, ignores unicode-range and should be limited to one font format. Apply it to the one or two fonts used above the fold.

Should I use Google Fonts or host fonts myself?

Neither is automatically faster, according to the guidance. Self-hosting is more likely to help when a CDN and HTTP/2 are in place, and then you take over WOFF2 compression and subsetting. Measure transfer time including connection setup for both options.

Why do icon fonts shift more than text fonts?

Their fallbacks often look very different and can mean something else, so the swap is more disruptive. Replacing icon fonts with SVG avoids the shift and helps accessibility.

Conclusion

Font-driven layout shift has three levers. Timing: request fonts early, preload only what the first screen needs, serve WOFF2 and subset. Behavior: use optional for body text and swap only where the brand font is the point. Geometry: tune the fallback with size-adjust and the ascent, descent and line-gap overrides so the swap barely moves anything. Verify each change in the lab by comparing line breaks, then in field data over its 28-day window. These steps aim at a steadier experience for visitors and do not guarantee any particular search ranking.

If you need technical guides like this written clearly and consistently, you can look at the SEO content writing service at Akua Adforce; scope and terms are listed on the product page.

0 Comments

No comments yet for this article.

Post a comment

Please log in to leave a comment. Login