CSS Self-Hosted Fonts

Self-hosted fonts are web font files stored on your own web server instead of being downloaded from a third-party font service.

Self-hosting gives you direct control over the font files and how they are delivered. The font files are uploaded with the other website files, defined in CSS with @font-face, and then applied to elements with the font-family property.

How Self-Hosting Works

With a self-hosted font, the font files are stored as part of your website. When the browser needs the font, it downloads the file from the location specified in your CSS.

The basic process is:

  1. Obtain a font that is licensed for web use.
  2. Choose the font formats needed by your website.
  3. Upload the font files to your web server.
  4. Define each font face with an @font-face rule.
  5. Apply the font using the font-family property.
  6. Provide a suitable fallback font.

Unlike a third-party hosted font, the browser retrieves the font directly from your website's server.

Choosing Font Files

WOFF2 is generally the preferred format for modern websites because it provides efficient compression and broad support in current browsers. WOFF can also be provided when support for older browsers is required.

CustomFont-Regular.woff2
CustomFont-Bold.woff2
CustomFont-Italic.woff2

A font family may contain separate files for different weights and styles. You only need to host the font files that the website actually uses.

Uploading Font Files

Font files can be stored in a dedicated folder so they are easy to organize and reference from your CSS.

css/
  styles.css
fonts/
  CustomFont-Regular.woff2
  CustomFont-Bold.woff2
index.html

The exact folder structure is up to you. What matters is that the URL used in the @font-face rule correctly points from the stylesheet to the font file.

Defining a Self-Hosted Font

Use the CSS @font-face rule to give the font a family name and tell the browser where its font file is located.

@font-face {
  font-family: "CustomFont";
  src: url("../fonts/CustomFont-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
}

The font-family descriptor creates the family name you will use in your CSS. The src descriptor identifies the font file, while font-weight and font-style describe the face contained in that file.

Font File Paths

The URL inside @font-face must point to the actual location of the font file. A relative URL is resolved relative to the stylesheet containing the @font-face rule.

src: url("../fonts/CustomFont-Regular.woff2") format("woff2");

If the CSS file is inside a css folder and the font files are inside a neighboring fonts folder, ../ moves up one directory before entering the fonts directory.

An incorrect font path is a common reason a self-hosted font does not appear. If the browser cannot find or load the font file, it will normally use the next available font in the font-family list.

Applying a Self-Hosted Font

After a font has been defined with @font-face, use its assigned family name with the normal font-family property.

h1 {
  font-family: "CustomFont", sans-serif;
}

The name used here must match the font-family name defined in the corresponding @font-face rule.

Multiple Font Weights and Styles

When a font family provides separate files for different weights or styles, define each face with its own @font-face rule while using the same family name.

@font-face {
  font-family: "CustomFont";
  src: url("../fonts/CustomFont-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
}
@font-face {
  font-family: "CustomFont";
  src: url("../fonts/CustomFont-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
}

The browser can then select the appropriate font file when a matching weight is requested.

p {
  font-family: "CustomFont", sans-serif;
  font-weight: 400;
}
strong {
  font-weight: 700;
}

Defining the correct weight and style for each font file allows normal CSS properties such as font-weight and font-style to select the appropriate face.

Font Fallbacks

A self-hosted font should be followed by one or more fallback fonts so text remains readable if the custom font cannot be loaded.

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

The browser first attempts to use CustomFont. If it is unavailable, Arial can be used, followed by the generic sans-serif family.

Font Licensing

Self-hosting a font places a copy of the font file on your web server where it can be downloaded by visitors' browsers. The font's license must therefore permit web use and distribution in this manner.

Do not assume that a desktop font can also be used as a web font. Check the license supplied by the font creator or distributor before uploading the font files to your website.

Important: Converting a font to WOFF or WOFF2 does not change its license. The original license must permit the font to be used and distributed as a web font.

Self-Hosted Font Performance

Every self-hosted font file is an additional resource the browser may need to download. Using several font families, weights, and styles can increase page size and make font management more complicated.

Custom fonts can be especially effective when used selectively for headings, branding, or a typeface designed specifically for a business. Standard system fonts may be a better choice for ordinary body text when the custom font does not provide an important part of the design.

When self-hosting fonts, use only the font files the website actually needs, prefer efficient formats such as WOFF2, and always provide suitable fallback fonts so the content remains readable if a custom font cannot be loaded.

Self-Hosted Font Example

Self-hosted fonts can be especially useful for distinctive headings, branding, or custom typefaces created specifically for a business. For ordinary body text, system fonts can often provide better performance and reliability without requiring additional font files to be downloaded.

The following example uses the Mailman script font stored on the website. The font is defined in a separate stylesheet and applied only to the heading, while the paragraph continues to use the standard Arial font.

<link rel="stylesheet" href="web-fonts/stylesheet-mailman.css">
h2 {
  font-family: "Mailman", cursive;
}

Open the example in the editor and notice how the decorative web font is limited to the heading rather than being used for the body text.

Play in Editor