How to Use CSS size-adjust to Reduce CLS
Web fonts often cause unexpected layout shifts when they swap with
system fallback fonts, degrading the user experience and hurting Core
Web Vitals scores. The CSS size-adjust descriptor solves
this problem by scaling fallback font glyphs to match the proportions of
the intended custom web font. By harmonizing the dimensions of both
fonts, developers can eliminate jarring text jumps during page load,
effectively minimizing Cumulative Layout Shift (CLS) without sacrificing
custom typography.
The Problem: Fallback Fonts and Layout Shift
When a browser loads a web page using a custom web font, it typically displays a system fallback font first to avoid invisible text (FOIT). When the custom font finishes downloading, the browser swaps it in (FOUT).
Because different typefaces have distinct x-heights, glyph widths, and line heights, this swap causes text blocks to expand or contract. Surrounding elements—such as images, buttons, and adjacent paragraphs—abruptly jump to accommodate the new text dimensions. This visual instability directly inflates a site's Cumulative Layout Shift (CLS) metric.
What is size-adjust?
Introduced as part of the CSS Fonts Module Level 4,
size-adjust is a font descriptor used inside the
@font-face rule. It applies a global scaling percentage to
the glyph outlines and font metrics of a specific font face.
Unlike the standard font-size property, which applies to
DOM elements, size-adjust modifies the font itself before
any element-level CSS is applied. Setting size-adjust: 90%,
for example, proportionally shrinks all glyphs and metric dimensions of
that font face to 90% of their default scale.
How size-adjust
Reduces CLS
To eliminate layout shifts, size-adjust is applied to a
custom fallback @font-face definition rather than the
primary web font. The process involves:
- Creating a local
@font-facealias for a standard system font (such as Arial, Times New Roman, or system-ui). - Applying a calculated
size-adjustpercentage to that fallback font so its character widths match the incoming web font as closely as possible. - Defining the fallback font in the
font-familystack immediately after the primary web font.
When the browser renders text, the fallback font occupies almost the exact same space as the custom web font. When the web font finally loads and replaces the fallback, the document layout remains stable, resulting in near-zero layout shift.
Example Implementation
/* 1. Define the custom web font */
@font-face {
font-family: 'Open Sans';
src: url('/fonts/OpenSans-Regular.woff2') format('woff2');
font-display: swap;
}
/* 2. Define the adjusted fallback font */
@font-face {
font-family: 'Open Sans Fallback';
src: local('Arial');
size-adjust: 105.5%; /* Adjusts Arial's dimensions to match Open Sans */
ascent-override: 101%;
descent-override: 28%;
line-gap-override: 0%;
}
/* 3. Apply the font family stack */
body {
font-family: 'Open Sans', 'Open Sans Fallback', sans-serif;
}Complementary Override Descriptors
While size-adjust handles the proportional width and
general scale of the glyphs, vertical alignment can still cause
micro-shifts. For maximum CLS reduction, size-adjust is
commonly paired with three vertical metric override descriptors:
ascent-override: Defines the height of the font above the baseline.descent-override: Defines the depth of the font below the baseline.line-gap-override: Defines the recommended line gap space.
Together with size-adjust, these properties allow system
fallback fonts to mimic the exact bounding box of any web font, ensuring
a visually seamless transition and a high-performing Core Web Vitals
score.