Skip to content

AURA LOGIC / INDEX

INDEPENDENT DIGITAL STUDIO

04 / WEBSITE & BUSINESS INSIGHTS [62 OF 94]
← RETURN TO ALL INSIGHTS
Performance • 12 min read • PUBLISHED 2026-03-10 • UPDATED 2026-03-10

Web Fonts for Zero CLS: Variable Fonts and Subsets

Web fonts without layout shift, self-hosting variable fonts, subsetting glyphs and using size-adjust fallbacks to reach zero CLS and a faster LCP.

Aura Logic
Aura Logic EDITORIAL GUIDES
Website design and planning • Editorial insights
EXECUTIVE SUMMARY // AEO SYNTHESIS COVENANT

Web fonts are one of the most common causes of late Largest Contentful Paint (LCP) and Cumulative Layout Shift (CLS). Third-party font CDNs (such as Google Fonts) add DNS lookups, TLS handshakes and render-blocking FOIT (Flash of Invisible Text). Self-hosting a single variable font, slicing it to the glyphs you actually use, and calibrating the fallback with CSS size-adjust removes most of the shift.

[+]
[+]
[+]
[+]
Loading Website Fonts Without Layout Jumps — cover card with a constellation of connected points

The Silent Killer of Editorial Web Performance

On a site whose job is to look considered, typography does most of the work. A well-chosen serif or geometric sans-serif says care, restraint and craft before a word is read.

Yet across the web, typography remains the primary architectural bottleneck undermining Core Web Vitals.

According to the HTTP Archive’s Web Almanac for 2025, fonts accounted for 139 KB of the median desktop home page and 122 KB of the median mobile home page, behind only images and JavaScript — and web fonts were present on 88% of websites in the same year’s crawl.

Worse, standard implementation patterns produce two destructive visual anomalies:

  1. FOIT (Flash of Invisible Text): The browser hides headline text for up to 3 seconds while waiting for the remote font file to download, leaving blank whitespace on the screen and severely delaying Largest Contentful Paint (LCP). The CSS Fonts Level 4 specification recommends a 3s block period for font-display: block, and Google’s own font guidance notes that Chromium and Firefox block text rendering for up to three seconds by default.
  2. FOUT (Flash of Unstyled Text) & CLS (Cumulative Layout Shift): The browser renders text in a fallback font like Times New Roman or Arial, then abruptly swaps to the custom web font when it finishes downloading. Because the glyph geometries differ, line breaks shift, paragraph heights change, and Google’s CLS metric records the movement.
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│                 THE GEOMETRIC MISMATCH OF FONT SWAPPING (CLS)               │
│  └───────────────────────────────────────────────────────────────────────┘  │
│  SYSTEM FALLBACK (Arial):                                                   │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│   │ THE ARCHITECTURE OF YOUR OWN BUSINESS                               │   │
│  │ (Ascent: 1050, Descent: -210, Line-Height: 48px, 1 Line of Text)      │  │
│  └───────────────────────────────────────────────────────────────────────┘  │
│                                                                             │
│  CUSTOM WEB FONT SWAP (Bespoke Display Serif):                              │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │ THE ARCHITECTURE OF                                                   │  │
│  │ THE BUSINESS YOU ARE BUILDING                                         │  │
│  │ (Ascent: 1200, Descent: -320, Line-Height: 64px, Wraps to 2 Lines!)  │   │
│  └───────────────────────────────────────────────────────────────────────┘  │
│  RESULT: 16px Layout Jump on all child elements -> CLS Score: 0.18 (FAIL)   │
│                                                                             │

The example above is illustrative, but the threshold in it is not: Google treats a CLS of 0.1 or less as good, and anything above that as needing improvement.

At Aura Logic, we treat font loading not as an aesthetic afterthought, but as an exact engineering discipline. Through automated glyph subsetting, self-hosted variable font engines, and fallback font synthesis, we keep the layout still while the font arrives.


1. The Variable Font Revolution: From 5 Files to 1

A site with a typographic hierarchy usually ends up loading several static font binaries. Here is a typical set, for illustration:

  • Inter-Regular.woff2 (45 KB)
  • Inter-Medium.woff2 (46 KB)
  • Inter-SemiBold.woff2 (46 KB)
  • Inter-Bold.woff2 (47 KB)
  • Inter-Italic.woff2 (48 KB)

Total payload: 232 KB across 5 discrete HTTP requests.

The Variable Font Alternative

A variable font (woff2-variations) contains an entire continuous design space within a single compact binary file. Rather than switching files, the browser dynamically interpolates glyph contours along standardized axes:

  • wght (Weight: 100 to 900)
  • slnt (Slant: -10 to 0)
  • opsz (Optical Size: 6pt to 72pt)
/* Single font file delivers infinite weights without additional HTTP requests */
@font-face {
  font-family: 'AuraSans';
  src: url('/fonts/AuraSans-Variable.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: optional;
}

.heading-display {
  font-family: 'AuraSans', sans-serif;
  font-weight: 850;
  font-variation-settings: 'opsz' 48;
}

.body-caption {
  font-family: 'AuraSans', sans-serif;
  font-weight: 420;
  font-variation-settings: 'opsz' 14;
}

By consolidating multiple weights into a single variable binary, we eliminate 4 network round trips and, on the font set above, reduce the baseline payload by 60%. That percentage is our own arithmetic on our own files. The wider shift is not a secret: the Web Almanac found that 39.4% of desktop sites and 41.3% of mobile sites now use at least one variable font.


2. Compile-Time Glyph Subsetting with Python FontTools

Commercial fonts ship with global character support, including Cyrillic, Greek, Devanagari, mathematical symbols, and historical currency ligatures. For a site in English and Spanish, most of those glyphs are dead weight.

Using Python’s fonttools and pyftsubset utility, Aura Logic executes compile-time font subsetting during the static build phase:

# Automated font slicing pipeline for Aura Logic
pyftsubset AuraDisplay.ttf \
  --output-file=AuraDisplay-Subset.woff2 \
  --flavor=woff2 \
  --layout-features='kern,liga,calt' \
  --unicodes="U+0020-007F,U+00A0-00FF,U+2010-201F,U+2026,U+2190-2193" \
  --desubroutinize

Breakdown of the Subsetting Flag Parameters:

  • --flavor=woff2: Encodes directly to WOFF2 using the Brotli compression algorithm.
  • --unicodes: Selects only ASCII Printable, Latin-1 Supplement (covering accented characters for Spanish, French, and German), quotation marks, and directional arrows (→, ↗).
  • --desubroutinize: Optimizes PostScript outline paths for faster GPU rasterization.
│      ┌───────────────────────────────────────────────────────────────────────┐      │
│                 GLYPH SUBSETTING PAYLOAD COMPARISON AUDIT                           │
│      └───────────────────────────────────────────────────────────────────────┘      │
│ FONT CONFIGURATION           │ GLYPH COUNT          │ BINARY FILE SIZE (WOFF2)      │
├──────────────────────────────┼──────────────────────┼───────────────────────────────┤
│ Full Commercial TTF          │ 1,840 glyphs         │ 380.4 KB                      │
│ Standard WOFF2 Export        │ 1,840 glyphs         │ 142.6 KB                      │
│ Subsetting: Latin-1 Extended │ 340 glyphs           │ 34.2 KB                       │
│     Aura Micro-Subset (Latin)│ 164 glyphs           │ 18.8 KB (87% Savings)         │
└──────────────────────────────┴──────────────────────┴───────────────────────────────┘

The audit above is of our own font set, measured with the same pyftsubset command shown above, not a published benchmark.


3. Mathematical Fallback Calibration: Synthesizing Zero CLS

The single greatest cause of font-related layout shift is the discrepancy between system fallback metrics and custom web font metrics.

When the web font loads, the browser replaces Arial with the custom font. If the x-height or ascent differs, the paragraph expands or contracts, shifting the entire DOM.

Modern CSS provides font metric override descriptors inside @font-face that allow us to force the system fallback font to adopt the exact bounding box of the custom font:

/* 1. Custom Web Font Definition */
@font-face {
  font-family: 'AuraEditorial';
  src: url('/fonts/AuraEditorial-Subset.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: optional;
}

/* 2. Metric-Adjusted Fallback Font */
@font-face {
  font-family: 'AuraEditorial-Fallback';
  src: local('Times New Roman');
  ascent-override: 96.4%;
  descent-override: 24.2%;
  line-gap-override: 0%;
  size-adjust: 104.8%;
}

/* 3. Typographic Application */
.hero-title {
  font-family: 'AuraEditorial', 'AuraEditorial-Fallback', serif;
  font-size: 3.5rem;
  line-height: 1.15;
}

How size-adjust Works Mathematically:

size-adjust = (Custom Font UPM / Fallback Font UPM) × 100% = 104.8%

In the example above, the browser paints the hero headline using Times New Roman, scaling each glyph by 104.8% and overriding the ascent to 96.4%. Those two percentages are values we calculated for our own font pair, not published constants. What is published is the mechanism: MDN defines size-adjust as a percentage multiplier applied to a font’s glyph outlines and metrics, and ascent-override as the metric CSS uses to lay out line boxes in an inline formatting context.

When AuraEditorial.woff2 finishes downloading, it slides into the exact same pixel coordinates. Not a single surrounding DOM element shifts by a single pixel.

In our own builds that holds CLS at 0.000 for the text that uses the calibrated fallback.


4. The font-display: optional Contract

In high-performance web architecture, you must choose between two UX paradigms:

  • font-display: swap: Shows text in the fallback font first, then displays it in the custom font once it loads, at the risk of an aesthetic flicker if the font arrives after the block period — the CSS Fonts Level 4 specification gives swap an extremely small block period, 100ms or less, and an infinite swap period.
  • font-display: optional: Google’s font guidance lists a 100ms block period and no swap period. If the font binary is in browser cache or loads within 100ms, it renders immediately. If the network is slow, it renders the metric-calibrated fallback and does not swap during the current view—preventing mid-reading shifts. The font is stored in cache for subsequent page views.

For a site where the typography is a large part of the design, font-display: optional combined with preloading the primary hero font is the safest choice:

<!-- In Astro head layout -->
<link 
  rel="preload" 
  href="/fonts/AuraEditorial-Subset.woff2" 
  as="font" 
  type="font/woff2" 
  crossorigin 
/>

Summary: The Performance Dividends

By applying mechanical rigor to web font delivery:

  • Font transfer weight drops from 232 KB to 18.8 KB on the set measured above.
  • Largest Contentful Paint (LCP) improves on mobile connections, because the font is no longer a render-blocking request sitting on the critical path.
  • Cumulative Layout Shift (CLS) is held at 0.000 by the metric-calibrated fallback.
  • Dependency on external third-party CDNs (Google Fonts) is eliminated, which also means one less request that leaves your own infrastructure.
STRUCTURED PROTOCOL // FAQS

Frequently Addressed Technical Inquiries

Why does loading Google Fonts from fonts.googleapis.com hurt Core Web Vitals? [+]

Loading fonts from an external CDN forces the browser to establish two sequential TCP and TLS handshakes to fonts.googleapis.com and fonts.gstatic.com before downloading font binaries. On cellular networks, this network overhead introduces 300ms to 700ms of render delay, triggering Flash of Invisible Text (FOIT) and delaying Largest Contentful Paint (LCP).

What is glyph subsetting and how much bandwidth does it save? [+]

Glyph subsetting is the automated process of stripping unused characters, scripts, and OpenType ligature tables from a font file. Commercial fonts ship with global character coverage, so a site published in two languages carries a set of glyphs it never renders. On our own font set, the full file was 1,840 glyphs and 380.4 KB as a TTF, 142.6 KB as a WOFF2, and 18.8 KB after subsetting to the Latin range we actually use. Those are measurements of our files, not a published benchmark, but the effect is the same on any font set: the bytes you never ship are the bytes you never download.

How do CSS size-adjust and ascent-override eliminate Cumulative Layout Shift (CLS)? [+]

When a custom web font finishes downloading and replaces the fallback system font (such as Arial or Times New Roman), differences in glyph bounding boxes cause the entire text block to change height, shifting surrounding layout elements down the screen. CSS size-adjust, ascent-override, and descent-override recalibrate the fallback font's dimensions to match the custom font's exact bounding box, which removes most of the shift when the swap happens.

Sources

  1. [1] CSS Fonts Module Level 4 | W3C Verifies the font-display timings this article quotes: that block gets a short block period of 3s and an infinite swap period, that swap and fallback get an extremely small block period of 100ms or less, and that with optional the block and swap periods are treated as expired, so the font is never swapped in once the fallback has been painted.
  2. [2] Best practices for fonts | web.dev Verifies the font-display table this article relies on (block 2-3 seconds, swap 0ms, fallback 100ms and 3 seconds, optional 100ms with no swap) and the statement that Chromium and Firefox block text rendering for up to 3 seconds by default.
  3. [3] size-adjust CSS at-rule descriptor | MDN Web Docs Verifies the mechanism behind the fallback calibration in this article: size-adjust is a percentage multiplier on a font's glyph outlines and metrics, with an initial value of 100%.
  4. [4] Fonts (Chapter 1) | Web Almanac 2025 | HTTP Archive Verifies the font figures this article quotes: that web fonts were found on roughly 88% of websites in 2025, and that 39.4% of desktop sites and 41.3% of mobile sites use at least one variable font.
  5. [5] Page Weight (Chapter 14) | Web Almanac 2025 | HTTP Archive Verifies the font payload figure this article quotes: fonts accounted for 139 KB on the median desktop home page and 122 KB on the median mobile home page, behind images and JavaScript.
  6. [6] Web Vitals | web.dev Verifies the Cumulative Layout Shift threshold used in the diagram in this article: Google treats a CLS of 0.1 or less as good, and anything above it as needing improvement.
#Web Fonts #Core Web Vitals #CLS Optimization #Variable Fonts #WOFF2 Subsetting
CONTINUED DOCTRINE // RELEVANT INTELLIGENCE

Related articles

EXPLORE ALL [94] ARTICLES →
YOUR NEXT STEP

WANT IT REVIEWED FOR YOUR BUSINESS?

The above is general. Tell me about your business and I will review business websites for your case: what applies, what does not, and in what order.

Business websites ↗
09/DISCUSS YOUR PROJECT
[ PROJECT ENQUIRIES ]

TELL US ABOUT
YOUR BUSINESS.

Tell us what your business does, what you need and your approximate budget. We will review the scope and next steps with you.

DISCUSS YOUR PROJECT
[email protected] ↗
↗VIEW MY FIVERR PROFILE ↗•WRITTEN SCOPE•ENGLISH & SPANISH
START A CONVERSATION ↗DIRECT CONTACT
Work directly with the studio • Read our Privacy Policy.
Tell me what your business needs
LOCATION & COLLABORATION
Based in Mexico City • Working with international clients
STUDIO • GLOBAL CLIENT COVERAGE
Mexico City (HQ)
11:15:00 AM
New York (EST)
01:15:00 PM
London (GMT)
06:15:00 PM
Tokyo (JST)
02:15:00 AM
Worldwide Client Partnerships
Direct Senior Studio Review within 24 Hours

Explore all business guides ↗

YOUR NEXT STEP

READY TO IMPROVE YOUR WEBSITE?

Describe what you want your website to do for your business. Jorge will help you define the scope, understand the cost and choose the next step.