Free tool - no signup
Font Fallback Metrics Calculator
Pick the web font you load and the fallback it lands on. Get size-adjust, ascent-override, descent-override and line-gap-override, a paste-ready @font-face, and the pixels of layout shift that remain. Every number is read from a real font file. Nothing leaves your browser.
The file is read in this tab. Nothing is uploaded. WOFF2 cannot be read here, so use the TTF, OTF or WOFF version of the same font.
- size-adjust
- 107.12%
- ascent-override
- 90.44%
- descent-override
- 22.52%
- line-gap-override
- 0%
In a 560px column, content below moves 0px when the real font lands (2.9px without the descriptors). Across containers from 240 to 960px wide, the line count still differs at 1% of widths (24% without them).
| Measure | Fallback as is | With the descriptors |
|---|---|---|
| Content below the text moves | 2.9px | 0px |
| Container widths where the line count differs | 24% | 1% |
| First baseline moves | 0.8px | 0px |
| Text width against the real font | -6.9% | -0.3% |
| Lines (fallback vs real font) | 3 vs 3 | 3 vs 3 |
The swap happens once the font file arrives. Whether anyone notices depends on how closely the fallback matched its metrics, and on how many lines of text sit above the first thing the reader was about to click.
The swap happens once the font file arrives. Whether anyone notices depends on how closely the fallback matched its metrics, and on how many lines of text sit above the first thing the reader was about to click.
The swap happens once the font file arrives. Whether anyone notices depends on how closely the fallback matched its metrics, and on how many lines of text sit above the first thing the reader was about to click.
The dashed line marks where the real font's text block ends, computed from its metrics. The shaded block is the text as your browser draws it with the fallback. Where they meet, the swap moves nothing.
Where these numbers come from
Inter: Version 4.001;git-66647c0bb, read from
ofl/inter/Inter[opsz,wght].ttf at google/fonts commit
2eb0b48d5f, sha256 29160a80ff49.
Units per em 2048, ascent 1984, descent 494, line gap 0,
weighted average width 978.
Arial: Version 5.01.2x, read from
/System/Library/Fonts/Supplemental/Arial.ttf, sha256 525979822591.
Units per em 2048, ascent 1854, descent 434, line gap 67,
weighted average width 913.
How to use it
- Choose the web font you serve. If it is not listed, pick "Upload a font file" and give it a TTF, OTF or WOFF.
- Choose the fallback your visitors see first. Arial and Times New Roman cover Windows, macOS and most Linux desktops; Roboto covers Android and ChromeOS.
- Set the size, line height and the container width of the text you care about. A hero heading and a 16px paragraph behave differently, so run both.
- Copy the @font-face block and the
font-familyline under it. Put the adjusted fallback between your web font and the generic family.
What the four descriptors do
A font swap moves the page for two separate reasons. The new letters can be wider or narrower, so lines wrap in different places. And the new font can carry a different ascent, descent and line gap, so every line box changes height even when the words are identical. The descriptors fix both on the fallback, before the web font ever arrives.
size-adjust scales the fallback's glyphs until typical
English text is as wide as it will be in the web font. It is the ratio of
the two average widths, each divided by its own units per em.
ascent-override, descent-override and
line-gap-override then pin the vertical metrics to the web
font's values. They are divided by size-adjust first, because the browser
multiplies them by it again, and that is the detail hand-copied snippets
most often get wrong.
A worked pair: Inter over Arial
Inter's average width is 978 units on a 2048 em, Arial's is 913. The ratio is 1.0712, so Arial has to grow by 7.12%. Inter's ascent is 1984 units (96.9% of the em) and its descent 494 (24.1%); divided by 1.0712 they become 90.44% and 22.52%. Inter carries no line gap, which is why that value is 0%.
The vertical half matters more than people expect. Left alone, Arial's
line box at 16px with line-height: normal is 18.4px and
Inter's is 19.36px. That is 0.96px per line, so a twelve-line paragraph
ends up about 11.5px shorter before the swap than after it, even if every
word wrapped identically. A fixed line height such as 1.5 hides that part
and leaves only the wrapping, which is why the table lets you switch
between the two.
Checked against Fontaine and Capsize
The numbers are not typed in. A script reads each font file with
fontTools, measures the glyph advances and writes the table the tool
ships with, together with the file name, the google/fonts commit and the
file's sha256. The unit tests then compare that table with
@capsizecss/metrics 4.3.0, the data behind Fontaine and the
Next.js font loader, and compare the finished percentages with what
Fontaine 1.0.0 prints for the same pairs.
- Fourteen web fonts and three fallbacks were measured. Sixteen of the seventeen agree with Capsize on units per em, ascent, descent, line gap and average width, exactly.
- Inter over Arial: this tool 107.12%, 90.44%, 22.52%; Fontaine 107.1194%, 90.4365%, 22.518%. Playfair Display over Times New Roman: 111.26%, 97.25%, 22.56% against Fontaine's 111.2615%, 97.2483%, 22.5595%.
- Lato differs on average width only (884 here, 871 in Capsize). The google/fonts file is version 2.015, and Capsize's copy measures 1.5% narrower, which points to a different release of the family.
Checked in a browser
Agreeing with other tools proves the arithmetic, not the result. So the output was run in Chrome 152 on macOS on 2026-10-08, using the real Inter and Playfair Display files from google/fonts. The sample paragraph was laid out at every container width from 240 to 960px in 4px steps, 181 widths, in the real font, in the plain fallback, and in the fallback with this tool's @font-face.
- Inter over Arial: the adjusted fallback wrapped to the same number of lines as the real font at all 181 widths. The plain Arial differed at 42 of them (23%).
- Playfair Display over Times New Roman: 2 mismatches with the descriptors, 52 without (29%). Block heights were identical to the real font at the four widths checked.
- With Inter at its automatic optical size, which a self-hosted variable file uses at 16px, the adjusted fallback differed at 6 widths against 36 for the plain one.
- The calculator's own line-count prediction matched Chrome at all 181 widths for the plain Arial and for the adjusted one. For the real Inter it was off at 2 widths, which is the cost of ignoring kerning.
What the layout numbers are, and what they are not
The simulation sums glyph advance widths, wraps the sample text greedily at the container width you set, and compares the block height and first baseline of the fallback with the real font. It repeats the comparison from 240 to 960px in 4px steps to find how many widths still wrap to a different line count, because one lucky width proves little.
It ignores kerning and ligatures, and browsers round ascent and descent to whole pixels, so a real shift can differ by up to a pixel per line. It is also not a CLS score. CLS multiplies the moved distance by the share of the viewport that moved, and only your page knows that. Use the numbers to compare options, then confirm with a Lighthouse or field run.
Where fallback matching stops helping
Letter shapes do not follow metrics. A geometric sans like Space Grotesk over Arial can match width and height on average and still wrap a line differently at several container widths, because its capitals and its narrow letters sit far from Arial's. Pair a serif web font with a serif fallback and a sans with a sans; the tool warns when they mismatch.
system-ui is not one font, and two of its three faces
cannot be adjusted. It resolves to San Francisco on Apple devices, Segoe
UI on Windows and Roboto on Android and ChromeOS. Browsers do not hand
San Francisco to local(), and Segoe UI has no redistributable
file, so the tool offers Roboto for Android and ChromeOS and Arial for
the rest. The Roboto rule could not be exercised in a browser here,
because Roboto is not installed on the Mac used for testing; its metrics
come from the real file like every other entry. Variable fonts are
measured at their default instance, and several families default to
their lightest weight, so an uploaded variable file gets a warning when
its default weight is not 400. Icon fonts and non-Latin scripts need their
own measurement.
Common questions
- What is a font fallback and why does it need metrics?
- A fallback is the font the browser draws while your web font downloads. If its letters are wider or taller than the web font, the page reflows the moment the real file arrives, and that reflow is what Cumulative Layout Shift records. Metric overrides make the fallback occupy the same space, so the swap changes the letterforms and nothing else.
- Why does the calculator ask for an average width and not an exact one?
- Text is a mix of letters, so the useful number is the width of typical English text, not of one glyph. The tool weights each character by how often it appears in English prose (spaces and e, t, a, o dominate) and averages the glyph advances. Fontaine and the Next.js font loader use the same weighting, which is why the results here agree with theirs.
- Can I use this for a font that is not in the list?
- Yes. Choose "Upload a font file" and pick a TTF, OTF or WOFF file. The file is parsed in your browser tab with a small built-in reader, so nothing is uploaded. WOFF2 cannot be read because it is Brotli-compressed; use the TTF or WOFF version of the same family.
- Why is there no system-ui fallback for Mac and Windows?
- Because a @font-face cannot reach them. On macOS, system-ui is San Francisco, and in Chrome 152 none of the 13 names we tried for it (BlinkMacSystemFont and -apple-system among them) loaded through local(), so a rule built on them never matches. On Windows it is Segoe UI, which is not redistributable, so there was no file to measure. Arial is installed on every Mac and Windows machine and is the tested choice for both.
- Does this prevent layout shift completely?
- No. It closes the gap that comes from font metrics, which is usually the largest part. Text can still wrap differently at a few container widths because two fonts never share every glyph width, and browsers round ascent and descent to whole pixels. The table shows how many container widths still differ so you can judge the remainder.
- What happens in a browser that ignores these descriptors?
- Browsers drop descriptors they do not recognize, so the fallback face renders at its natural size and the page behaves as it did before you added the rule. You lose the improvement, not the page.
- Why can the Android result differ from the Arial one?
- Android phones do not ship Arial, so local("Arial") finds nothing and the browser moves to the next family in your stack. Add a second adjusted face that targets Roboto, the Android system font, and list both fallbacks. The calculator offers Roboto as a fallback for exactly that reason.
The wider picture is in font loading without the flash: font-display, preload and subsetting. Fluid heading sizes change the numbers above, so settle them in the clamp preview first, and check the pairing's reading sizes with the type scale calculator.