WBL Code LibraryFlow · 0.7 KB

Font swap without layout shift

Web fonts that arrive without moving a single line: a local font resized to the web font's exact footprint shows first, then swaps invisibly. With an overlay proof and an in-browser calculator for new fonts.

Does the fallback take the same room?

The black text is Archivo (the web font). Red is Arial with the overrides: what a visitor sees for the first few hundred milliseconds. Blue is plain Arial, what most sites show. Red sits on the black line for line; blue drifts, and that drift is the layout shift when the font arrives.

Colour, cuts and gray blending on Sunset since 2012. Two chairs, one appointment per stylist at a time, and nobody watching the clock. Walk-ins until 30 minutes before close.

Fallback calculator

For a font that isn't in build/font_fallbacks.json yet: pick its file (or a bundled one), get the CSS.

How to use it

Size
0.7 KB gzipped own code (JS 0.0 KB + CSS 0.7 KB; 1.2 KB raw)
Dependency
none (vanilla + native APIs)
Tag
Flow
Best for
Every site that uses a web font (all of them)

What it does

The pattern is CSS only: preload the woff2, declare it with font-display: swap, declare a 'Name Fallback' face on local(Arial) with size-adjust, ascent-override, descent-override and line-gap-override, and list both. The demo overlays the web font, the adjusted fallback and plain Arial so you can see the match. calc.js measures any font file against a local font in the browser (canvas: letter-frequency-weighted widths and the font's own ascent/descent) and prints the @font-face, no Python or fontTools needed.

When to use

Don't

Reduced motion, no JS, accessibility

Notes

Copy-ready snippet

<!-- Font swap without layout shift (WBL Code Library) -->
<!-- in <head>, before the stylesheet: -->
<link rel="preload" href="/fonts/Archivo-latin.woff2" as="font" type="font/woff2" crossorigin>
<style>
@font-face{font-family:'Archivo';font-weight:400 800;font-display:swap;src:url(/fonts/Archivo-latin.woff2) format('woff2')}
@font-face{font-family:'Archivo Fallback';src:local('Arial'),local('ArialMT'),local('Helvetica'),local('Liberation Sans');
  size-adjust:98.07%;ascent-override:89.73%;descent-override:21.41%;line-gap-override:0%}
h1,h2,h3{font-family:'Archivo','Archivo Fallback',sans-serif}
</style>

README.md · module.js · module.css · All modules