W3docs

CSS @font-face Rule

The @font-face rule defines online fonts to display. See some examples.

The CSS @font-face rule lets you load a custom font from a file you host (or a web service) and use it anywhere in your stylesheet. This means you are no longer limited to the handful of "web-safe" fonts that happen to be installed on every visitor's machine.

This page covers the font formats you can serve, how to write a robust @font-face declaration with fallbacks, the font-display property that controls loading behavior, the available font descriptors, and the alternative of using a hosted service such as Google Fonts.

How @font-face works

A @font-face rule does two things:

  1. It defines a name for the font with the font-family descriptor (for example, myFirstFont).
  2. It points to one or more font files with the src descriptor.

Once declared, you reference the font by that name in any normal font-family rule, exactly as you would a system font:

@font-face {
  font-family: 'myFirstFont';
  src: url('myfirstfont.woff2') format('woff2');
}

p {
  font-family: 'myFirstFont', sans-serif;
}

Always end the font-family stack with a generic fallback (such as sans-serif) so text is still readable if the font file fails to load.

Font formats

Browsers support several font file formats: ttf, otf, eot, svg, svgz, woff, and woff2. For the modern web you only need WOFF2 (with WOFF as a fallback for older browsers); the rest are legacy.

OTF-TTF

WOFF was created to provide a compressed, web-optimized alternative to OpenType and TrueType fonts, reducing file size and loading time. However, OpenType capabilities may interest lots of designers (such as ligatures).

EOT

Embedded Open Type format, created by Microsoft (the original innovators of @font-face) over 15 years ago, is the only format that IE8 and below will recognize when using @font-face.

SVG/SVGZ

Scalable Vector Graphics (Font) is a vector font format. However, SVG fonts have been deprecated and removed from all modern browsers. It is no longer recommended for use in new projects. SVGZ is the zipped version of SVG.

WOFF/WOFF2

Web Open Font Format, created for use on the web and developed by Mozilla together with other organizations, WOFF fonts often load faster than other formats because they use a compressed version of the structure used by the OpenType (OTF) and TrueType (TTF) fonts. WOFF2 is the new generation of WOFF and it has better compression.

When using custom fonts, we should take into account the following considerations:

  • The file size. It’s recommended to use options that have lighter versions.
  • The character set limitations. You can limit font sets to load only the fonts that are used.
  • System fonts for small screens. One of the solutions is to target larger screens when the custom font is loaded with @media.

Syntax

Syntax of CSS @font-face Rule

@font-face {
  font-properties
}

Example of the @font-face rule:

Example of CSS @font-face Rule with EOT, TTF, SVG, WOFF and WOFF2 formats

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      @font-face {
        font-family: 'myFont';
        src: url('webfont.woff2') format('woff2'),
             url('webfont.woff') format('woff'),
             url('webfont.ttf') format('truetype'),
             url('webfont.eot') format('embedded-opentype');
        font-display: swap;
      }
      div {
        font-family: myFont, sans-serif;
      }
    </style>
  </head>
  <body>
    <h2>@font-face example</h2>
    <div>
      The @font-face CSS at-rule specifies a custom font with which to display text; the font can be loaded from either a remote server or a locally-installed font on the user's computer. If the local() function is provided, specifying a font name to look for on the user's computer, and the user agent finds a match, that local font is used. Otherwise, the font resource specified using the url() function is downloaded and used.
    </div>
    <p>
      The @font-face at-rule may be used not only at the top level of a CSS, but also inside any CSS conditional-group at-rule.
    </p>
  </body>
</html>

Controlling loading with font-display

While a web font downloads, the browser has to decide what to show. The font-display descriptor controls this trade-off between a flash of invisible text (FOIT) and a flash of unstyled text (FOUT):

  • auto — the browser's default behavior (usually similar to block).
  • block — hide text briefly (up to ~3s), then show the web font. Causes FOIT.
  • swap — show fallback text immediately, then swap to the web font when it loads. Best for body copy because content is never invisible.
  • fallback — a short block period, then fallback; the web font only swaps in if it arrives quickly.
  • optional — like fallback, but the browser may skip the web font entirely on slow connections.

swap is the most common choice and is used throughout the examples below.

Browser Support

Deepest Possible Browser Support

This is the method having the deepest support. Before any styles, we should add the @font-face rule to the stylesheet.

@font-face rule

@font-face {
  font-family: 'MyWebFont';
  src: url('webfont.woff2') format('woff2'),
       url('webfont.woff') format('woff'),
       url('webfont.ttf') format('truetype'),
       url('webfont.eot') format('embedded-opentype');
  font-display: swap;
}

Then, it is used to style elements in the following way:

CSS @font-face rule

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

Practical Level of Browser Support

Since WOFF and WOFF2 are commonly being used, we can use the following:

CSS @font-face rule

@font-face {
  font-family: 'MyWebFont';
  src: url('myfont.woff2') format('woff2'), url('myfont.woff') format('woff');
  font-display: swap;
}

Super Progressive Browser Support

If we are working on WOFF, it can be expected that WOFF2 can be used at some point:

CSS @font-face Rule

@font-face {
  font-family: 'MyWebFont';
  src: url('myfont.woff2') format('woff2');
  font-display: swap;
}

Alternative Techniques

In some situations, it can be better to use a hosted font. This is offered by Google Fonts as a means to use their fonts. In the following code, @import is used to load a font from Google Fonts:

CSS @font-face Rule

@import url(//fonts.googleapis.com/css?family=Open+Sans);

Then it can be used to style elements:

CSS @font-face Rule

body {
  font-family: 'Open Sans', sans-serif;
}

A hosted service can have an advantage. It will probably include all the variations of the font file providing deep cross-browser compatibility, and there won’t be any need of hosting the files by ourselves.

CSS @font-face Rule

@import url(//fonts.googleapis.com/css?family=Open+Sans);
body {
  background: #efefef;
  font-family: 'Open Sans', sans-serif;
  font-size: 16px;
  line-height: 24px;
  padding: 50px;
}

In the same way, a stylesheet can be linked to the same asset in the <head> of the HTML document and not in the CSS.

HTML

<link href='//fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>

Then, the elements can be styled like the other methods:

CSS

body {
  font-family: 'Open Sans', sans-serif;
}

Again, the @font-face rules are imported but they are added to the HTML <head>:

CSS

body {
  background: #efefef;
  font-family: 'Open Sans', sans-serif;
  font-size: 16px;
  line-height: 24px;
  padding: 50px;
}

h1 {
  font-size: 30px;
  line-height: 45px;
  font-family: 'Open Sans', sans-serif;
}

Example of the @font-face rule using Google Fonts:

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <link href="https://fonts.googleapis.com/css?family=Courier+Prime:400,700&display=swap" rel="stylesheet" />
    <style> 
      h2{
      font-family: 'Courier Prime', monospace;
      font-weight:700;
      }
      div {
      font-family: 'Courier Prime', monospace;
      }
      p{
      font-family: 'Courier Prime', monospace;
      }
    </style>
  </head>
  <body>
    <h2>@font-face example</h2>
    <div>
      The @font-face CSS at-rule specifies a custom font with which to display text; the font can be loaded from either a remote server or a locally-installed font on the user's computer. If the local() function is provided, specifying a font name to look for on the user's computer, and the user agent finds a match, that local font is used. Otherwise, the font resource specified using the url() function is downloaded and used.
    </div>
    <p>
      The @font-face at-rule may be used not only at the top level of a CSS, but also inside any CSS conditional-group at-rule.
    </p>
  </body>
</html>

Values

Font DescriptorValuesDescription
font-familynameIt defines the font's name and it is a requirement.
srcURLIt defines the URL where the font will be downloaded and it is a requirement.
font-stretchnormal condensed ultra-condensed extra-condensed semi-condensed expanded semi-expanded extra-expanded ultra-expandedIt defines how the font will be stretched. Its default value is normal and it is optional.
font-stylenormal italic obliqueIt defines how the font will be styled. Its default value is normal and it is optional.
font-weightnormal bold 100 200 300 400 500 600 700 800 900It defines the font boldness. Its default value is normal and it is optional.
unicode-rangeunicode-rangeIt defines the range of unicode characters the font supports. Its default value is U+0-10FFFF and it is optional.

Using local() in src

Inside src you can list local('Font Name') before the url() entries. The browser will use a matching font already installed on the user's machine and only download the file if none is found, saving bandwidth:

@font-face {
  font-family: 'MyWebFont';
  src: local('My Web Font'),
       url('mywebfont.woff2') format('woff2');
  font-display: swap;
}

Practice

Practice
What is the purpose of the @font-face rule in CSS?
What is the purpose of the @font-face rule in CSS?
Was this page helpful?