Embedding Fonts as Data URIs in CSS

Learn how to embed WOFF and WOFF2 font files as data URIs in @font-face declarations to eliminate font loading flash and improve First Contentful Paint.

CSS

Detailed Explanation

Inline Fonts with Data URIs

Embedding web fonts as data URIs inside @font-face CSS declarations eliminates the font file request entirely. The font data is available as soon as the CSS is parsed, which can dramatically reduce Flash of Invisible Text (FOIT) and Flash of Unstyled Text (FOUT).

@font-face with Data URI

@font-face {
  font-family: 'CustomFont';
  src: url('data:font/woff2;base64,d09GMgABAAAAADw...') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

When Font Inlining Makes Sense

Font inlining is most effective in these scenarios:

  1. Critical text rendering — When the font is needed above the fold and FOIT is unacceptable
  2. Single-page applications — When the CSS is already bundled and cached
  3. Small icon fonts — Subset icon fonts under 20 KB compress well as data URIs
  4. Email templates — Where external font requests may be blocked

Font Format Recommendations

Format MIME Type Typical Size Support
WOFF2 font/woff2 Smallest Modern browsers
WOFF font/woff Small Wide support
TTF font/ttf Large Universal

Always prefer WOFF2 for data URIs because its compression produces the smallest Base64 payload.

Subsetting for Smaller Data URIs

Before inlining a font, subset it to include only the characters you need. A full Google Fonts file for Latin + Cyrillic might be 60 KB, but a subset with only Latin characters could be 15 KB. Tools like pyftsubset and Google Fonts' text parameter can generate subsets.

Trade-offs

  • Pro: Eliminates font file request, faster rendering
  • Pro: No CORS configuration needed
  • Con: Cannot be cached independently from CSS
  • Con: Increases CSS file size by ~33%
  • Con: If font changes, entire CSS cache is invalidated

Use Case

You are building a high-performance landing page where First Contentful Paint is critical, and you want the hero heading font to be available instantly without any font loading delay.

Try It — Data URL Generator & Decoder

Open full tool