Font Loading Strategies
FOIT vs FOUT, font-display values, and the Font Loading API. Choose the right strategy for optimal performance and user experience.
Quick Answer
Use font-display: swap for most websites. It shows fallback text immediately (avoiding FOIT) and swaps to your custom font when loaded. For performance-critical pages where you'd rather skip fonts than cause layout shift, use font-display: optional.
FOIT vs FOUT Explained
When a browser downloads a web font, it needs to decide what to show while waiting. This creates two fundamental behaviors that have different impacts on user experience:
FOIT
Flash of Invisible Text
- • Text is hidden while font loads
- • Users see blank space
- • Content is unreadable during load
- • Hurts Largest Contentful Paint (LCP)
- • Default in older browsers
Invisible until loaded
FOUT
Flash of Unstyled Text
- • Text shows in fallback font
- • Content is always readable
- • Swaps when custom font loads
- • Better for Core Web Vitals
- • Preferred modern approach
Readable immediately
The font-display Property
The font-display CSS property controls how fonts are displayed during loading. Add it to your @font-face rules:
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap; /* The key property */
}font-display Values
swap RecommendedShows fallback text immediately. Swaps to custom font when loaded, regardless of how long it takes.
Use when: You want text always visible and accept the swap.
blockHides text for up to 3 seconds (block period). Then shows fallback and swaps when loaded.
Use when: Only for icon fonts where invisible icons are acceptable briefly.
fallbackVery short block period (~100ms), then fallback. Only swaps if font loads within ~3 seconds.
Use when: You want minimal FOIT and can accept the font might not load on slow connections.
optional Performance-firstUses font only if already cached. No block period, no swap. Falls back permanently if not instant.
Use when: Performance is critical and you'd rather skip custom fonts than cause any visual disruption.
autoBrowser decides. Usually behaves like block. Avoid—be explicit.
Use when: Never. Always specify a value explicitly.
Strategy Comparison
| Strategy | FOIT | FOUT | LCP | CLS Risk |
|---|---|---|---|---|
font-display: swap ✓ | No | Yes | Good | Some risk |
font-display: block | Yes (short) | Yes | Poor | Some risk |
font-display: fallback | Minimal | Maybe | Good | Reduced |
font-display: optional | No | No | Best | None |
Font Loading API | Configurable | Configurable | Configurable | Configurable |
Font Loading API
The Font Loading API (document.fonts) provides JavaScript control over font loading. Use it for advanced scenarios.
Detect When Fonts Load
// Wait for all fonts to load
document.fonts.ready.then(() => {
console.log('All fonts loaded!');
document.body.classList.add('fonts-loaded');
});
// Check if a specific font is loaded
document.fonts.check('16px Inter'); // true/false
// Wait for a specific font
document.fonts.load('400 16px Inter').then(() => {
console.log('Inter loaded!');
});FOUT with a Class Pattern
A popular pattern: hide custom fonts until loaded, then add a class to enable them:
/* CSS: Use fallback by default */
body {
font-family: system-ui, sans-serif;
}
/* When fonts are loaded, use custom font */
.fonts-loaded body {
font-family: 'Inter', system-ui, sans-serif;
}// JavaScript: Add class when fonts load
if (document.fonts) {
document.fonts.ready.then(() => {
document.documentElement.classList.add('fonts-loaded');
});
} else {
// Fallback for older browsers
document.documentElement.classList.add('fonts-loaded');
}Browser Support: The Font Loading API is supported in all modern browsers (96%+ global support). For older browsers, use a fallback that assumes fonts are loaded.
Modern Loading Approaches
1. Simple: font-display: swap + Preload
Best for most websites. Combine font-display: swap with preloading critical fonts:
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>2. Performance-First: font-display: optional
For maximum performance. First visit uses system fonts; subsequent visits use cached custom fonts. Zero CLS.
Great for: Landing pages, e-commerce, any site where speed > brand consistency
3. Critical Font Strategy
Different strategies for different fonts based on importance:
- • Body text:
font-display: swap+ preload - • Headings:
font-display: swap - • Decorative:
font-display: optional - • Icon fonts:
font-display: block
4. Minimize CLS with Font Matching
Reduce layout shift by matching your fallback font's metrics to your custom font:
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-display: swap;
/* Adjust fallback metrics */
size-adjust: 100%;
ascent-override: 90%;
descent-override: 20%;
}Tools like Fallback Font Generator can calculate these values.
Recommendations by Use Case
Most Websites
- Use
font-display: swap - Preload 1-2 critical fonts
- Subset fonts to reduce file size
- Use WOFF2 format
E-commerce / Landing Pages
- Consider
font-display: optionalfor zero CLS - System fonts on first visit is acceptable
- Custom fonts load from cache on return visits
Brand-Heavy Sites
- Use
font-display: swap - Always preload critical fonts
- Use Font Loading API for controlled transitions
- Match fallback font metrics to minimize CLS
Icon Fonts
- Use
font-display: block - Brief invisibility is better than showing wrong characters
- Consider switching to SVG icons for better performance
Frequently Asked Questions
What is FOIT in web fonts?
FOIT (Flash of Invisible Text) is when text is hidden while a web font loads. Users see blank space until the font downloads. This hurts user experience and Core Web Vitals, especially Largest Contentful Paint.
What is FOUT in web fonts?
FOUT (Flash of Unstyled Text) is when browsers show a fallback font while the custom font loads, then swap when ready. Content is always readable, but there's a visual "flash" during the swap.
Which font-display value should I use?
Use font-display: swap for most sites—it shows fallback text immediately. Use font-display: optional for performance-critical pages where avoiding visual disruption matters more than custom fonts on first load.
How does font-display: optional work?
With optional, the browser uses the custom font only if it's already cached. First-time visitors see system fonts. On subsequent visits, they see your custom font with zero loading delay and zero layout shift.
Does font-display cause layout shift (CLS)?
swap and fallback can cause CLS when fonts load and text reflows. optional causes zero CLS. You can minimize CLS with any strategy by matching fallback font metrics.
Related Guides
Optimize Your Fonts Now
Upload any font and get an optimized WOFF2 with proper CSS output including font-display recommendations.
Try Sift Free