Font Converter

@font-face Optimization

Write optimal @font-face declarations for maximum performance. Master format order, local() fallbacks, unicode-range splitting, and font descriptor optimization.

Key Takeaways

  • • List WOFF2 first in src for best compression
  • • Use local() to check for installed system fonts
  • • Always include font-display: swap
  • • Use unicode-range for language-based splitting

The Optimal @font-face Declaration

Here is a complete, optimized @font-face rule with all recommended properties.

@font-face {
  /* Font identification */
  font-family: 'CustomFont';

  /* Source stack - order matters! */
  src: local('Custom Font'),           /* Check system first */
       local('CustomFont'),             /* Alternative name */
       url('/fonts/custom.woff2') format('woff2'),  /* Best format */
       url('/fonts/custom.woff') format('woff');    /* Fallback */

  /* Weight and style */
  font-weight: 400;
  font-style: normal;

  /* Loading behavior */
  font-display: swap;

  /* Character subset (optional) */
  unicode-range: U+0000-00FF;
}

Format Order: WOFF2 First

Browsers download the first format they support. List formats from best to fallback.

/* Correct order - WOFF2 first (30% smaller) */
src: url('/fonts/font.woff2') format('woff2'),
     url('/fonts/font.woff') format('woff');

/* For maximum compatibility (rarely needed) */
src: url('/fonts/font.woff2') format('woff2'),
     url('/fonts/font.woff') format('woff'),
     url('/fonts/font.ttf') format('truetype');

/* Modern browsers only (recommended) */
src: url('/fonts/font.woff2') format('woff2');

Format Support

FormatBrowser SupportRecommendation
woff296%+ globalAlways use
woff98%+ globalFallback only
ttf/otfLegacyRarely needed
eotIE onlySkip unless IE needed

Using local() for System Fonts

The local() function checks if a font is already installed on the user's system, avoiding unnecessary downloads.

@font-face {
  font-family: 'Open Sans';
  src: local('Open Sans'),        /* Full name */
       local('OpenSans'),          /* PostScript name */
       local('Open Sans Regular'), /* With weight */
       url('/fonts/opensans.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}

When to Use local()

  • • Popular fonts (Open Sans, Roboto)
  • • System fonts with web versions
  • • Fonts bundled with OS

When to Skip local()

  • • Custom/proprietary fonts
  • • When version control matters
  • • Privacy concerns (fingerprinting)

Font Weight and Style Declarations

Declare explicit weights and styles to prevent browser faux-bold/italic synthesis.

/* Each weight needs its own @font-face */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/* Variable font - weight range */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-variable.woff2') format('woff2-variations');
  font-weight: 100 900; /* Range */
  font-style: normal;
  font-display: swap;
}

Unicode-Range Splitting

Split fonts by character set so browsers only download needed subsets.

/* Latin characters - loads for English */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153;
  font-display: swap;
}

/* Cyrillic - only loads for Russian, etc. */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-cyrillic.woff2') format('woff2');
  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1;
  font-display: swap;
}

/* Greek - only loads when Greek chars used */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-greek.woff2') format('woff2');
  unicode-range: U+0370-03FF;
  font-display: swap;
}

Google Fonts Approach

Google Fonts automatically splits fonts into ~20 subsets per language. This is why their CSS files contain many @font-face rules.

Fallback Font Matching

Use font metric overrides to match fallback fonts to your custom font, preventing layout shift.

/* Adjusted fallback to match custom font */
@font-face {
  font-family: 'CustomFont-Fallback';
  src: local('Arial');
  size-adjust: 105%;       /* Scale to match */
  ascent-override: 90%;    /* Adjust ascenders */
  descent-override: 22%;   /* Adjust descenders */
  line-gap-override: 0%;   /* Adjust line gap */
}

body {
  font-family: 'CustomFont', 'CustomFont-Fallback', Arial, sans-serif;
}

Metric Override Properties

  • size-adjust - Scale the font up/down to match x-height
  • ascent-override - Adjust space above baseline
  • descent-override - Adjust space below baseline
  • line-gap-override - Adjust extra line spacing

Complete Example

/* Optimized font-face for a typical website */

/* Primary font - Regular */
@font-face {
  font-family: 'Inter';
  src: local('Inter'),
       url('/fonts/inter-regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF;
}

/* Primary font - Medium */
@font-face {
  font-family: 'Inter';
  src: local('Inter Medium'),
       url('/fonts/inter-medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF;
}

/* Primary font - Bold */
@font-face {
  font-family: 'Inter';
  src: local('Inter Bold'),
       url('/fonts/inter-bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF;
}

/* Adjusted fallback */
@font-face {
  font-family: 'Inter-Fallback';
  src: local('Arial');
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
}

/* Usage */
body {
  font-family: 'Inter', 'Inter-Fallback', system-ui, sans-serif;
}

Additional Resources

Generate @font-face CSS

Use our CSS generator to create optimal @font-face declarations automatically.

Open CSS Generator
Sarah Mitchell

Written & Verified by

Sarah Mitchell

Product Designer, Font Specialist

@font-face Optimization FAQs

Common questions about CSS font declarations