Best Practices: Adding Fonts to Your Website
Learn how to add web fonts the right way with modern best practices for performance, typography, caching, and user experience.
December 15, 2025
Best Practices: Adding Fonts to Your Website
How to load web fonts the right way (performance, clarity, and control)
Typography does more than make your site look good — it impacts readability, brand presence, load time, and even SEO. But the act of adding fonts to a website involves more nuance than dropping a <link> tag into your <head>.
This guide walks through modern best practices for loading and managing web fonts so you get fast performance, visual stability, and full design flexibility.
1. Choose Fonts Wisely (Less Is More)
Every font file adds weight to your page. That means:
- More HTTP requests
- More time before text is visually “final”
- More potential layout shifts
General guideline:
Use 1–2 font families and only the weights and styles you truly need.
Example weights you might keep:
- 300 (light)
- 400 (regular)
- 500 (medium)
- 700 (bold)
- Optional: italic variants if used in UI or editorial content
Avoid shipping full libraries “just in case.” Intentional choices here pay off everywhere else.
2. Self-Host Your Fonts When Possible
Self-hosting your font files (WOFF2) gives you:
- Faster load times
- Better caching and control
- More consistent privacy/compliance
- Fewer render-blocking DNS lookups
In most modern builds, self-hosting is preferred over third-party providers like Google Fonts or other font CDNs.
3. Use Separate @font-face Blocks by Weight & Style
Browsers match fonts based on:
font-familyfont-weightfont-style
Declaring a @font-face block per variation is both idiomatic and flexible:
@font-face {
font-family: 'MyFont';
src: url('/fonts/MyFont-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'MyFont';
src: url('/fonts/MyFont-Bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
Then anywhere in your CSS:
h1 {
font-family: 'MyFont';
font-weight: 700;
}
This pattern is clean, predictable, and stable across all layout engines.
4. Prefer WOFF2 for Modern Browsers
The most performant and compressed web font format is WOFF2.
Unless you support very old browsers, you can safely avoid WOFF/TTF/EOT and keep your CSS simple:
@font-face {
font-family: 'MyFont';
src: url('/fonts/MyFont-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
Fewer formats means less complexity and a smaller surface area for bugs.
5. Use font-display for Better UX
font-display controls how the browser handles text before a web font loads.
Common values:
swap— instant text using a fallback font, then swap to the web font when readyoptional— ultra-performant; the browser may skip loading the font on poor connectionsblock— hides text until the font loads (can hurt UX and Core Web Vitals)
Recommended defaults:
- Use
swapfor most body and UI text - Consider
optionalfor less-critical fonts on content-heavy pages
Example:
@font-face {
font-family: 'MyFont';
src: url('/fonts/MyFont-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
6. Preload Critical Fonts
Preload only the fonts used above the fold — usually:
- Body regular (400)
- Headline bold (700)
<link
rel="preload"
href="/fonts/MyFont-Bold.woff2"
as="font"
type="font/woff2"
crossorigin
/>
Overusing preload can actually hurt performance. Be selective and focus on the initial viewport.
If your fonts are served from a different domain or static asset host, remember to:
- Add the appropriate CORS headers
- Use
crossoriginon your<link>tags
7. Build a Smart Fallback Stack
Fallback fonts matter during the “swap” period and when fonts fail to load.
Use system UI stacks for clean fallbacks:
:root {
--sans-stack: system-ui, -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
body {
font-family: 'MyFont', var(--sans-stack);
}
This helps reduce layout shift and preserves legibility even before web fonts load.
Where supported, you can also experiment with font-size-adjust to keep the perceived size consistent between fallback and final fonts:
body {
font-family: 'MyFont', var(--sans-stack);
line-height: 1.5;
font-size-adjust: 0.5;
}
8. Subset Fonts for Large Projects
If your typeface includes many scripts (Latin + Cyrillic + Greek + symbols, etc.), consider breaking them into smaller subsets, each with a unicode-range.
@font-face {
font-family: 'MyFont';
src: url('/fonts/MyFont-Latin.woff2') format('woff2');
font-weight: 400;
font-style: normal;
unicode-range: U+000-5FF;
font-display: swap;
}
Benefits:
- Smaller download sizes per user
- Browsers only load the subsets they actually need
This is especially helpful for global sites with traffic from many regions.
9. Consider Variable Fonts
Variable fonts allow a single file to contain multiple weights or styles:
@font-face {
font-family: 'MyFont VF';
src: url('/fonts/MyFont-Variable.woff2') format('woff2');
font-weight: 300 800;
font-style: normal;
font-display: swap;
}
Then in your CSS:
h1 {
font-family: 'MyFont VF', system-ui, sans-serif;
font-weight: 700;
}
strong {
font-weight: 600;
}
small {
font-weight: 300;
}
Benefits:
- One request instead of many
- Smooth interpolation between weights (great for animations)
- Flexible design without bloating your asset list
Just note: if you truly only use a single weight and style, a static font may still be lighter in total bytes.
10. Avoid Icon Fonts — Use SVG Instead
Icon fonts have several drawbacks:
- Accessibility issues (icons are technically text glyphs)
- Dependence on font loading to display icons correctly
- Inconsistent rendering and alignment across platforms
Modern best practice is to use SVG icons instead:
- Inline SVGs for flexible styling and animation
- SVG sprite sheets for reusability and caching
You’ll get sharper icons, better accessibility, and fewer font-related headaches.
11. Cache Fonts Aggressively
On your server or CDN, set your font responses with a long cache lifetime:
Cache-Control: public, max-age=31536000, immutable
Then version your file names when you update fonts:
/fonts/MyFont-Regular.v1.woff2/fonts/MyFont-Regular.v2.woff2
This lets browsers keep fonts cached for months while still allowing you to roll out updates safely.
12. Reduce Layout Shifts (CLS)
Web fonts can cause layout jumps if not handled properly. To minimize Cumulative Layout Shift (CLS):
- Use fallbacks with similar metrics to your web fonts
- Preload only the fonts used in the initial viewport
- Set explicit line heights rather than relying on defaults
- Avoid design patterns where text dramatically changes size when the web font loads
Good typography is as much about stability and predictability as it is about style.
Conclusion
Fonts are one of the most visible parts of your brand — but they’re also one of the most common performance bottlenecks.
By following these best practices, you can:
- Keep your site fast
- Ensure clean, consistent typography
- Reduce visual shifts and layout jumps
- Improve accessibility and user experience
- Maintain full control over your design system
Whether you’re building a simple marketing site or a complex application, the way you load fonts matters. Apply these principles and your visitors (and your Core Web Vitals) will thank you.
More Blog Posts

December 19, 2025
Practical Ways to Integrate Blockchain in Your Web Stack
A practical guide for web developers on when and how to effectively use blockchain technology in modern web applications.

December 15, 2025
Best Practices: Adding Fonts to Your Website
Learn how to add web fonts the right way with modern best practices for performance, typography, caching, and user experience.

December 14, 2025
How Caching on the Web Works
A practical guide explaining how server cache, browser cache, and modern cache-busting techniques work—plus solutions for WordPress, React/Vue, and static sites.