CSS @font-face At-Rule

The @font-face at-rule defines a custom font family that can be used throughout a stylesheet. It allows web pages to load font files from a server or use available local fonts, providing more control over typography than relying only on system-installed fonts.

@font-face Syntax

@font-face {
  font-family: "Custom Font";
  src: url("fonts/custom-font.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

The @font-face at-rule contains descriptors that identify a font family, locate its font file, and describe its available styles.

The font-family descriptor assigns a name to the font. The src descriptor specifies where the browser can find the font file.

Once the font is defined, its family name can be used with the CSS font-family property.

How @font-face Works

Normally, browsers display text using fonts available on the user's device. The @font-face at-rule allows a stylesheet to define additional fonts using downloadable font files.

First, declare the font with @font-face. Then apply the declared family name to the elements that should use it.

@font-face {
  font-family: "Site Font";
  src: url("fonts/site-font.woff2") format("woff2");
}
body {
  font-family: "Site Font", Arial, sans-serif;
}

The browser attempts to use the custom font when rendering the page. If the font is unavailable, it can use the next font in the font-family list.

The declared family name does not need to match the original name stored inside the font file.

The font file must exist at the specified location, and its license must permit the intended use.

@font-face Descriptors

The following descriptors define how a custom font is loaded and used.

Descriptor Description
font-family Defines the name used to reference the custom font family.
src Specifies one or more local or external font sources.
font-style Identifies the font face as normal, italic, or oblique.
font-weight Identifies the supported font weight or weight range.
font-stretch Identifies the supported font width or width range.
font-display Controls how text is displayed while the font loads.
unicode-range Specifies the Unicode characters covered by the font face.
font-feature-settings Specifies initial OpenType feature settings for the font face.
font-variation-settings Specifies initial variation-axis settings for a variable font.
ascent-override Overrides the font's ascent metric.
descent-override Overrides the font's descent metric.
line-gap-override Overrides the font's line-gap metric.
size-adjust Adjusts glyph outlines and associated font metrics by a specified percentage.

The font-family and src descriptors are essential for defining a usable downloadable font face. Other descriptors provide additional control over font selection, loading, and rendering.

Font Formats

Web fonts can be provided in several file formats. The browser must support the format to load the font successfully.

Format Extension Description
WOFF2 .woff2 Compressed web font format recommended for modern websites.
WOFF .woff Earlier compressed web font format with broad browser support.
TrueType .ttf Common font format that can also be loaded by browsers.
OpenType .otf Font format supporting advanced typographic features.

WOFF2 is generally the preferred format for modern web fonts because it provides efficient compression.

The src descriptor can provide multiple sources. The browser selects the first source it can successfully use.

@font-face {
  font-family: "Custom Font";
  src: local("Custom Font"),
       url("fonts/custom-font.woff2") format("woff2"),
       url("fonts/custom-font.woff") format("woff");
}

The local() function checks for an installed font. The url() sources provide downloadable alternatives.

Font Weights and Styles

Different font files can be assigned to the same family using separate @font-face rules. This allows the browser to select the appropriate file for normal, bold, or italic text.

@font-face {
  font-family: "Site Font";
  src: url("fonts/site-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
}
@font-face {
  font-family: "Site Font";
  src: url("fonts/site-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
}
body {
  font-family: "Site Font", sans-serif;
}
strong {
  font-weight: 700;
}

When the browser encounters bold text, it can select the font face defined with font-weight: 700.

Variable fonts can support a range of weights within a single font file.

@font-face {
  font-family: "Variable Font";
  src: url("fonts/variable-font.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
}

The weight range tells the browser which values the variable font face supports. The font file must contain the corresponding variation data.

Font Display

The font-display descriptor controls how text is displayed while a downloadable font is loading.

Value Description
auto Uses the browser's default font loading behavior.
block Allows a short period of invisible text followed by a period when a fallback font may be replaced.
swap Displays fallback text immediately and replaces it when the custom font becomes available.
fallback Uses a short invisible-text period and a limited opportunity to replace the fallback font.
optional Allows the browser to keep the fallback font if loading the custom font would be disruptive.

The swap value is useful when displaying text immediately is more important than avoiding a later font change.

@font-face {
  font-family: "Site Font";
  src: url("fonts/site-font.woff2") format("woff2");
  font-display: swap;
}

Choosing an appropriate value helps balance text visibility, loading performance, and layout stability.

@font-face Example

The following example loads a custom font and applies it to page headings while keeping a system font as a fallback.

@font-face {
  font-family: "Heading Font";
  src: url("fonts/heading-font.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
h1, h2, h3 {
  font-family: "Heading Font", Arial, sans-serif;
}
p {
  font-family: Arial, sans-serif;
}

The headings use the custom font when it loads successfully. Paragraphs continue using Arial or another available sans-serif font.

The example uses a placeholder font filename. Replace it with the path to an actual WOFF2 font file before using the code on a website.

Browser Support

The @font-face at-rule is widely supported in modern browsers. Support for individual font formats and advanced descriptors can vary. Visit Can I Use? and search for CSS @font-face for compatibility information.

Specifications

The @font-face at-rule is defined in the CSS Fonts specifications, which describe downloadable font faces, font selection, and font-related descriptors.

CSS Fonts Module Level 4