CSS Web Fonts

Learn how to use custom web fonts in your projects with @font-face, Google Fonts, and optimize font loading for better performance

What are Web Fonts?

Web fonts allow you to use custom fonts on your websites that aren't limited to the fonts installed on user's devices. With CSS, you can load fonts from your server using@font-face or from external services like Google Fonts.

Web Font Technologies:

  • @font-face - Load custom fonts from your server
  • Google Fonts - Free font library with CDN delivery
  • Variable Fonts - Single font file with multiple variations
  • Font Services - Adobe Fonts, Fonts.com, etc.
Custom Web Font
Light Weight Variant
Serif with Italic
Monospace Font Example

Web Font Properties Reference

Property/RuleDescriptionValues/Usage
@font-faceDefines custom fonts to be loaded from serverfont-family, src, font-weight, font-style, font-display
srcSpecifies the source of the font fileurl(), format(), local()
font-displayControls how fonts are displayed while loadingauto, block, swap, fallback, optional
font-weightSpecifies weight for font variantsnormal, bold, 100-900 (in @font-face)
font-styleSpecifies style for font variantsnormal, italic, oblique (in @font-face)
unicode-rangeDefines range of Unicode characters supportedU+0000-00FF, U+0100-024F, etc.
@importImports external fonts (Google Fonts)@import url('https://...')
font-feature-settingsControls advanced typographic features'liga', 'clig', 'kern', etc.
font-stretchSelects normal, condensed, or expanded facenormal, condensed, expanded, 50-200%

Web Font Properties in Action

Example Code

/* CSS Web Fonts */

/* Using @font-face to embed custom fonts */
@font-face {
  font-family: 'MyCustomFont';
  src: url('fonts/mycustomfont.woff2') format('woff2'),
       url('fonts/mycustomfont.woff') format('woff');
  font-weight: normal;
  font-style: normal;
  font-display: swap; /* Controls font display behavior */
}

@font-face {
  font-family: 'MyCustomFont';
  src: url('fonts/mycustomfont-bold.woff2') format('woff2'),
       url('fonts/mycustomfont-bold.woff') format('woff');
  font-weight: bold;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'MyCustomFont';
  src: url('fonts/mycustomfont-italic.woff2') format('woff2'),
       url('fonts/mycustomfont-italic.woff') format('woff');
  font-weight: normal;
  font-style: italic;
  font-display: swap;
}

/* Using the custom font */
body {
  font-family: 'MyCustomFont', Arial, sans-serif;
}

/* Variable fonts */
@font-face {
  font-family: 'VariableFont';
  src: url('fonts/variablefont.woff2') format('woff2-variations');
  font-weight: 100 900; /* Range of weights supported */
  font-stretch: 75% 125%; /* Range of widths supported */
  font-style: oblique 0deg 20deg; /* Range of styles supported */
  font-display: swap;
}

.variable-font-example {
  font-family: 'VariableFont', sans-serif;
  font-weight: 650; /* Any value within the supported range */
  font-stretch: 110%; /* Any value within the supported range */
}

/* Using Google Fonts with @import */
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,700;1,400&display=swap');

.roboto-font {
  font-family: 'Roboto', sans-serif;
  font-weight: 400;
}

.open-sans-font {
  font-family: 'Open Sans', sans-serif;
  font-weight: 700;
  font-style: italic;
}

/* Using Google Fonts with link tag (in HTML) */
/* <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;800&display=swap" rel="stylesheet"> */

.montserrat-font {
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
}

/* Font loading strategies with font-display */
.font-display-auto {
  font-display: auto; /* Browser's default behavior */
}

.font-display-block {
  font-display: block; /* Short block period, infinite swap period */
}

.font-display-swap {
  font-display: swap; /* Very small block period, infinite swap period */
}

.font-display-fallback {
  font-display: fallback; /* Very small block period, short swap period */
}

.font-display-optional {
  font-display: optional; /* Very small block period, no swap period */
}

/* Using CSS variables with web fonts */
:root {
  --primary-font: 'Roboto', sans-serif;
  --heading-font: 'Montserrat', sans-serif;
  --code-font: 'Source Code Pro', monospace;
}

body {
  font-family: var(--primary-font);
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--heading-font);
}

code, pre {
  font-family: var(--code-font);
}

/* Performance optimization techniques */
.optimized-font-loading {
  font-display: swap; /* Show text immediately with fallback, then swap */
}

/* Preloading critical fonts */
/* Add to HTML <head>: <link rel="preload" href="fonts/critical.woff2" as="font" type="font/woff2" crossorigin> */

/* Using unicode-range for subsetting */
@font-face {
  font-family: 'SubsetFont';
  src: url('fonts/subset-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF; /* Latin characters only */
  font-display: swap;
}

/* Local font fallback */
.local-fallback {
  font-family: 'CustomFont', 'Arial', sans-serif;
}

/* Font feature settings for advanced typography */
.advanced-typography {
  font-feature-settings: 'liga' on, 'clig' on, 'dlig' on;
  /* ligatures, contextual ligatures, discretionary ligatures */
}

/* Using font-stretch for condensed/expanded variants */
.condensed-text {
  font-stretch: condensed;
}

.expanded-text {
  font-stretch: expanded;
}

Web Font Techniques in Detail

@font-face Rule

The @font-face rule allows you to define custom fonts that can be loaded from your server. You need to specify the font family name and the source URL(s) for the font files.

@font-face {
font-family: 'MyFont';
src: url('myfont.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}

Google Fonts

Google Fonts provides a free, easy-to-use library of web fonts. You can include them via a link tag in your HTML or an @import rule in your CSS.

<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
--- OR ---
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');

Font Display Strategies

The font-display property controls how a font is displayed based on whether and when it is downloaded and ready to use.

swap - Text appears immediately with fallback, then swaps
block - Briefly hides text until font loads
fallback - Compromise between swap and block
optional - Browser may not load font if slow connection

Variable Fonts

Variable fonts contain multiple variations of a typeface in a single file, allowing for fine-grained control over weight, width, and other attributes.

@font-face {
font-family: 'VariableFont';
src: url('font.woff2') format('woff2-variations');
font-weight: 100 900;
font-stretch: 75% 125%;
}

Best Practices for Web Fonts

Performance Optimization

  • Use WOFF2 format for best compression
  • Subset fonts to include only needed characters
  • Preload critical fonts with rel="preload"
  • Use font-display: swap for better perceived performance
  • Consider system fonts for body text with custom fonts for headings
  • Use variable fonts to reduce the number of font files

Common Mistakes to Avoid

  • Loading too many font weights and styles
  • Not providing adequate fallback fonts
  • Using font formats that aren't widely supported
  • Not optimizing font files for web use
  • Ignoring font loading performance impacts
  • Not testing on various devices and connections

Font Loading Strategies

  • Standard loading - Let browser handle font loading normally
  • FOIT (Flash of Invisible Text) - Browser hides text until font loads
  • FOUT (Flash of Unstyled Text) - Show fallback first, then swap
  • Critical FOFT - Load only critical fonts first, then others
  • Font loading API - Use JavaScript to control font loading

Ready to Try It Yourself?

Experiment with web fonts in our interactive editor. Try different font loading strategies, compare Google Fonts with @font-face, and see the performance impact of various approaches.

< PreviousNext >