---
tags:
  - wordpress
  - fonts
  - css
  - cls
  - optimization
title: Mastering font-display for CLS and Perceived Performance
---

# Mastering font-display for CLS and Perceived Performance

When a browser loads a web font, there is a brief moment where the font file hasn't arrived yet, but the text content is ready to be painted. The `font-display` CSS property tells the browser how to handle this "limbo" state.

Choosing the right value is critical for **Cumulative Layout Shift (CLS)** and **First Contentful Paint (FCP)**.

## 1. The Values Explained

### `font-display: block` (The Default)
*   **Behavior:** The text is invisible (transparent) for up to 3 seconds while waiting for the font. If it loads, it swaps. If not, it shows the fallback.
*   **Pros:** No "Flash of Unstyled Text" (FOUT).
*   **Cons:** "Flash of Invisible Text" (FOIT). Users see a blank screen. **Bad for PageSpeed.**
*   **Use Case:** Icon fonts (FontAwesome) where a fallback character would look broken.

### `font-display: swap` (The Standard Recommendation)
*   **Behavior:** The browser shows the fallback font (e.g., Arial) *immediately*. Once the web font loads, it swaps it in.
*   **Pros:** Text is readable instantly (Great FCP).
*   **Cons:** The swap causes a visual "jump" or re-flow (CLS) if the custom font is wider/narrower than Arial.
*   **Use Case:** Body text, headings, and most content.

### `font-display: optional` (The CLS Killer)
*   **Behavior:** The browser gives the font a very short window (100ms) to load. If it's not there, it uses the fallback font and **never swaps**. The custom font is downloaded in the background and used on the *next* page view.
*   **Pros:** **Zero Layout Shift.** The text never changes shape after the first paint.
*   **Cons:** First-time visitors might see Arial instead of your brand font.
*   **Use Case:** Critical optimization for mobile devices on slow networks where layout stability is more important than branding.

## 2. Reducing CLS with `swap`

If you use `swap` (which most sites do), you must minimize the layout shift caused by the font switching.

### The Problem
Your custom font "Inter" might be 10% wider than "sans-serif" (Arial). When the swap happens, a paragraph might jump from 3 lines to 4 lines, pushing everything down.

### The Solution: Metric Overrides
In 2026, CSS allows you to tweak the fallback font to match the dimensions of your web font using `ascent-override`, `descent-override`, and `size-adjust`.

```css
/* 1. Define the Web Font */
@font-face {
  font-family: 'MyBrandFont';
  src: url('my-brand-font.woff2') format('woff2');
  font-display: swap;
}

/* 2. Define a Tuned Fallback */
@font-face {
  font-family: 'MyBrandFallback';
  src: local('Arial'); /* Use a system font */
  /* Adjust these numbers until it matches MyBrandFont exactly */
  ascent-override: 90%;
  descent-override: 20%;
  size-adjust: 95%; 
}

/* 3. Use the Stack */
body {
  font-family: 'MyBrandFont', 'MyBrandFallback', sans-serif;
}
```

**Tip:** Use tools like the "Font Style Matcher" or Chrome DevTools to find the exact percentage values.

## 3. Summary Strategy

1.  **Icons:** Always use `font-display: block`.
2.  **Body Text:** Use `font-display: swap` combined with **Metric Overrides** to prevent the jump.
3.  **Extreme Performance:** Use `font-display: optional` if you are failing Core Web Vitals solely due to font shifts and can't get overrides to work perfectly.

## Related Guides
*   [[wordpress-local-fonts|Hosting Google Fonts Locally]]
*   [[wordpress-font-preloading|Advanced Font Optimization: Preloading Strategies]]
*   [[wordpress-woff2-vs-woff|WOFF vs. WOFF2]]
*   [[wordpress-font-metric-overrides|Calculating Font Metric Overrides with DevTools]]