How to Reduce Font Layout Shift With Fallback Fonts
Why the page jumps when your web font loads, and the CSS that makes the fallback font fit.
1. What Font Layout Shift Is
When a page loads, the browser often shows text in a fallback font (such as Arial) while the web font downloads. When the web font arrives, the text switches to it. If the two fonts have different widths or line heights, lines wrap differently and everything below the text jumps. That jump counts toward Cumulative Layout Shift (CLS), one of Google's Core Web Vitals.
Google rates a CLS of 0.1 or less as good and above 0.25 as poor. Fonts are rarely the only cause of shift, but on text-heavy pages they are a common one, and it is one of the easier causes to fix.
2. Why Fallback Fonts Cause the Jump
Every font has built-in measurements. Two of them matter most here:
- Glyph width. Wider letters mean fewer words per line, so paragraphs get taller or shorter after the swap.
- Vertical metrics. Ascent, descent and line gap decide how tall each line box is, even at the same
font-sizeandline-height.
Inter, for example, is noticeably wider than Arial, so a paragraph set in Arial first and then Inter will wrap differently. You can either stop the swap from happening or make the fallback measure like the web font.
3. First Fixes: Load Fonts Smarter
Before adjusting fallbacks, reduce how long the fallback is visible and how much the swap matters:
Preload the font that matters most
Preload only the font file used above the fold, usually the regular weight of your body or heading font.
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
Choose the right font-display value
swap shows the fallback immediately and swaps later, which is fast but can shift. optional gives the web font a very short window and otherwise keeps the fallback for that page view, which avoids shift but can mean some visitors do not see your font on first load. block hides text briefly, which can hurt the first impression. For most sites, swap plus a well-matched fallback is the best balance.
Load fewer font files
Each weight and style is a separate download. Use only the weights you need, or use one variable font file. Subsetting to the languages you support also shrinks files. See our web font performance guide and variable fonts guide.
4. The Main Fix: A Metric-Matched Fallback
CSS lets you define your own fallback by pointing an @font-face rule at a local system font and adjusting its metrics so it takes the same space as the web font. Four descriptors do the work:
size-adjustscales the fallback's glyphs so average letter width matches the web font.ascent-override,descent-overrideandline-gap-overrideset the vertical metrics so line boxes have the same height.
Here is a worked example for Inter with Arial as the base fallback. The values come from the font's real metrics (average glyph width, ascent, descent, line gap):
@font-face {
font-family: 'Inter Fallback';
src: local('Arial'), local('Liberation Sans'), local('Arimo');
size-adjust: 107.12%;
ascent-override: 90.44%;
descent-override: 22.52%;
line-gap-override: 0%;
}
body {
font-family: 'Inter', 'Inter Fallback', sans-serif;
}
The overrides are percentages of the scaled font size, which is why the vertical values are smaller than the font's raw ascent and descent: they are divided by the size-adjust ratio. Browsers that do not support these descriptors ignore them, so the fallback behaves as it did before.
5. Choosing the Base Fallback and local() Names
The fallback has to be installed on the visitor's device for local() to work. Arial, Times New Roman and Courier New are available on almost every Windows and macOS system, and these are the usual base choices for sans-serif, serif and monospace fonts. Linux and Android often lack them but ship metric-compatible clones, so list those in src too:
- Arial:
Liberation Sans,Arimo - Times New Roman:
Liberation Serif,Tinos - Courier New:
Liberation Mono,Cousine
6. How to Check That It Worked
- Lighthouse or PageSpeed Insights: the layout shift audits list the elements that moved, including text affected by font swaps.
- Chrome DevTools: in the Performance panel, record a page load and check the Layout Shifts track. In Rendering, enable Layout Shift Regions to see shifts highlighted.
- Throttle the network. Fast connections can hide the problem because the font arrives before first paint. Test on a slow connection setting.
- Compare field data. Lab tests only show one load. The CLS numbers in Search Console show what real visitors experience, with a delay.
7. If You Use a Framework
Some tools generate this for you. Next.js, through its next/font module, creates an adjusted fallback font automatically. For other setups, the open-source Capsize project and the Fontaine plugin calculate and inject the same kind of rules. If you write plain CSS or use a CMS, a generated @font-face rule like the one above works with no build step.
Font Layout Shift Checklist
Frequently Asked Questions
What is a good CLS score?
Google considers a Cumulative Layout Shift of 0.1 or less good, between 0.1 and 0.25 as needing improvement, and above 0.25 as poor. This is measured for the whole page, not only fonts.
Does font-display: swap cause layout shift?
It can. Swap shows the fallback font first and then switches to the web font, and if the two have different metrics the text reflows. A fallback adjusted with size-adjust and the metric overrides reduces that shift.
What do size-adjust and ascent-override do?
size-adjust scales a font's glyphs, and ascent-override, descent-override and line-gap-override set the vertical metrics used for line boxes. Applied to a local fallback font, they make it take nearly the same space as your web font.
Will this make my CLS exactly zero?
No. It usually reduces the shift from fonts a lot, but bold and italic text, other languages, and other page elements can still move. Treat it as a way to shrink the jump, and test your own pages.
Does Next.js already do this?
Yes. The next/font module generates an adjusted fallback font automatically. If you use plain CSS or another framework, you can add the same kind of @font-face rule yourself.
Does this work with Google Fonts loaded by a link tag?
Yes. Load the font as usual, define the fallback @font-face in your own CSS, and list its name after the web font in your font-family stack.