Use Variable Font For Better Performance
Tags: webdev, webperf
Published: 2022-05-03 16:52:33

Do you know when we are loading more than 2-3 font styles on our website, it is better to use Variable Font to reduce font payload and increase performance ⚡️

![variable-vs-normal-font-with-different-weights](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dma4e209663pld8y3xpb.png)
 
## What is Variable Font?
Variable Font is a single font file with multiple axes of variation.

![variable-font-demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/njc6orr8w2e8iy2y8iyz.gif)

The interesting part of the variable font is we can set any intermediate value of the axis as shown in above demo 🤯

For example, if we use normal font than we can only set standard supported font-weights such as 300,400,700 etc. but in case of variable font we can set font-weight to any intermediate value such as 390, 450 etc.

## What is axis in variable font?

> In variable fonts, “axis” usually refers to a single aspect of a typeface’s design that can be altered by the user.
&mdash; [Google Fonts Knowledge](https://fonts.google.com/knowledge/glossary/axis_in_variable_fonts)

There are 5 standard axes of variations defined by W3C. However, font can have any custom axis as well.

Axis is defined using four-letter tag.

Standard axis is written in small-case. 5 standard axes are:
→ wght (Weight)
→ wdth (Width)
→ ital (Italic)
→ slnt (Slant)
→ opsz (Optical Size)

Custom axis is written in upper-case such as:
→ GRAD (Grade)

Different web fonts have a different number of axes of variation. 

We can check all the open source variable fonts with their axes at [Google Variable Fonts](https://fonts.google.com/variablefonts).

## How to Download Variable Font?
If we are loading font from Google Fonts service, then it will automatically generate correct font-face rules and serve Variable Font to the compatible user device when we try to use multiple styles of a web font on a web page 🎉

But, if we are self-hosting fonts on our server, then we need to download and serve variable font manually.

If we are using any proprietary font, then the font package may already contain variable font. 

But, if we are using any Google Font, then we can download optimised variable font from Google Fonts by following this step-by-step tutorial on [how to download variable font from Google Fonts](https://www.codewithshripal.com/tutorials/web-development/how-to-download-variable-font).

## Configure @font-face rule for variable font
If we are loading web font using Google Fonts, then we don't need to do anything as Google Fonts service automatically generate CSS with correct @font-face rules to use variable font.

But, if we are self-hosting the variable font, then we need to write @font-face rules.

If the variable font doesn't have `ital` axis, then `@font-face` rule can be written as follows:

```css
@font-face {
  font-family: 'Inter';
  font-weight: 100 900;   // wght axis
  font-style: oblique 0deg 10deg; // slnt axis
  src: url('/fonts/inter-variable-font.woff2') format('woff2 supports variations'),
       url('/fonts/inter-variable-font.woff2') format('woff2-variations'),
       url('/fonts/inter-variable-font.woff2') format('woff2');
}
```

If the variable font has `ital` axis, then we need to write two `@font-face` rules. One for normal style variable font and another for italic style variable font.

```css
/* normal styled Roboto Serif variable font */
@font-face {
  font-family: 'Roboto Serif';
  font-weight: 100 900;   // wght axis
  font-stretch: 50% 150%; // wdth axis 
  font-style: normal;
  src: url('/fonts/roboto-serif-variable-normal.woff2') format('woff2 supports variations'),
       url('/fonts/roboto-serif-variable-normal.woff2') format('woff2-variations'),
       url('/fonts/roboto-serif-variable-normal.woff2') format('woff2');
}

/* italic styled Roboto Serif variable font */
@font-face {
  font-family: 'Roboto Serif';
  font-weight: 100 900;   // wght axis
  font-stretch: 50% 150%; // wdth axis 
  font-style: italic;     // ital axis is boolean, so no range.
  src: url('/fonts/roboto-serif-variable-italic.woff2') format('woff2 supports variations'),
       url('/fonts/roboto-serif-variable-italic.woff2') format('woff2-variations'),
       url('/fonts/roboto-serif-variable-italic.woff2') format('woff2');
}
```

In the above code, we are using same url with different formats for backward compatibility.

- "woff2 supports variations" => latest standard syntax

- "woff2-variations" => deprecated syntax

- "woff2" => not standard but browsers still render variable font with just file format

## How to use Variable Font?
For standard axis such as `wght`, `wdth`, `slnt`, `ital` we can use their respective property to set value. Mapping of axis and their respective css property is as shown below:
`wght` => `font-weight`
`wdth` => `font-stretch`
`ital`, `slnt` => `font-style`

For standard `opsz` axis and any custom axis, we need to set value using `font-variation-settings` property.

Below is an example code to show how to set values of different axes of variable font.

```css
body {
  font-family: 'Roboto Serif', serif;
  font-weight: 425; // sets wght axis value
  font-stretch: 110%; // sets wdth axis value
  font-style: normal; // sets ital axis value
  font-variation-settings: 'opsz' 50, 'GRAD' 80;
}

.decorative-text {
  font-family: 'Roboto Serif', serif;
  font-weight: 700; // sets wght axis value
  font-style: italic; // sets ital axis value
}

.slant-text {
  font-family: 'Inter', sans-serif;
  font-style: oblique -5deg; // sets slnt axis value
}
```

We can set values of standard axes using `font-variation-settings` as well but it is recommended to use their respective property to set value so that we can keep the browser from attempting to render font with any invalid value of the axis.

```css
body {
  font-family: 'Roboto Serif', serif;
  
  /* Valid but not recommended */
  font-variation-settings: 'wdth' 110, 'wght' 425;
  
  /* Recommended to set value using standard css property */
  font-weight: 425;
  font-stretch: 110%;  
}
```
## What about browser compatibility?
Variable Font is very well supported in around [91%](https://caniuse.com/variable-fonts) of active browser/OS versions as of May, 2022.

While loading font from Google Fonts, it automatically takes care to serve variable font only to compatible devices.

While self-hosting variable font, we can implement backward browser compatibility using `@supports` feature-query as shown below:

```css
// Inter variable font
@font-face {
  font-family: "InterVariable";
  font-weight: 100 900;
  font-style: oblique 0deg 10deg;
  src: url("/fonts/inter-latin-variable-full-font.woff2") format("woff2 supports variations"),
      url("/fonts/inter-latin-variable-full-font.woff2") format("woff2-variations"),
      url("/fonts/inter-latin-variable-full-font.woff2") format("woff2");
}

/* ----------- Non-variable Inter font-face rules ----------- */
// thin Inter font
@font-face {
  font-family: "Inter";
  font-weight: 300;
  src: url("/fonts/inter-latin-thin.woff2") format("woff2")
}

// regular Inter font
@font-face {
  font-family: "Inter";
  font-weight: 400;
  src: url("/fonts/inter-latin-regular.woff2") format("woff2")
}

// bold Inter font
@font-face {
  font-family: "Inter";
  font-weight: 700;
  src: url("/fonts/inter-latin-bold.woff2") format("woff2")
}

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

@supports (font-variation-settings: 'wdth' 450) {
 body {
    font-family: 'InterVariable', sans-serif;
 }
}
```

In above code we are creating one `@font-face` rule for using variable font. We are also creating separate `@font-face` rules for different styles of a font-family.

After that we are setting font-family to variable font only if it is supported by using `@supports` feature-query. So, compatible devices/browsers will use `InterVariable` font while non-compatible devices/browsers will use normal `Inter` font.

## Conclusion
That's how we can use variable font today irrespective of if we are loading web font from Google Fonts service or we are self-hosting the variable font, which results in better performance of the website.

Using variable font is just one of the many font loading optimization strategies for having better performance and better UX of a website.

If you want to learn more about other strategies to speed up web font loading in your website 🚀 and make font loading UX better, check out [modern optimization strategies for loading web fonts] (https://www.codewithshripal.com/articles/web-development/modern-optimizations-for-loading-web-font) article. That article explains in-detail about all the issues that occur when we use web font and how to resolve all those issues and thus provide better performance, UX and SEO for a website.