Switching to variable fonts

March 03, 2019 · 8 min read

Ever since I first learned about variable fonts, I’ve wanted to use them in my own work. After learning that Source Serif and Inter both had variable versions, I started switching this site over to use them. Here’s how I implemented the change, and what I learned along the way.

What are variable fonts?

Variable fonts are a new1 type of font file. Instead of requiring individual files for bold and light weights, or regular or italic variations, you only need a single variable file.

A responsive lettering example, courtesy of Erik van Blokland.
A responsive lettering example, courtesy of Erik van Blokland.

Why use variable fonts? In addition to technical simplicity (1 font file instead of multiple), variable fonts tend to come in smaller files than their more traditional cousins. Smaller files mean faster load times. Faster load times mean a better internet.

How I implemented variable fonts

I started with Clearleft’s case study of implementing variable fonts. The instructions they provide are incredibly detailed and useful, so I won’t try to re-create them here.

Before I switched to variable fonts, I was loading Source Serif in Roman and Italic at a two different weights. I used typekit’s CSS-only loader, as it was super-speedy compared to the javascript equivalent. To get those two fonts from Typekit’s server took 4 requests, bringing the page to a total of 8 requests2.

First Byte Start Render Requests Bytes in Speed Index
Typekit fonts 0.21s 0.80s 8 80 KB 0.82s

My initial attempt at including a variable version of Source Serif, along with introducing Inter, resulted in a surprisingly substantial increase in most metrics.

First Byte Start Render Requests Bytes in Speed Index
Typekit 0.21s 0.80s 8 80 KB 0.82s
Variable 0.22s (-0.1) 0.70s (-2) 6 (+464) 544 KB (+0.19) 1.12s

Looking into this, I realized that the variable font files were huge: Inter weighs in at 387kb, making up most of the difference. What happened? I thought variable fonts were supposed to be small?

It turns out that the variable font files I was using include a massive amount of characters: Diacritics for many languages, Cyrillic characters, Greek characters, and so on. I didn’t need most of those; I write in english, and system fonts can support automatic translations.

So I used a tool called glyphhanger to subset my fonts to just latin characters, removing most of the characters I wouldn’t need. In the case of Inter, this resulted in a 300kb reduction — that’s a 78% reduction.

With the new subset fonts, my numbers were looking much better:

First Byte Start Render Requests Bytes In Speed Index
Typekit 0.21s 0.80s 8 80 KB 0.82s
Variable (subset) 0.21s (-0.2) 0.60s (-2) 6 (+82) 162 KB (-0.17) 0.65s

Fanstastic! The upsides were great:

And there was only one downside:

But wait! Because I am serving the fonts myself, I have better control over caching. Before I made this update, I was relying on Typekit’s caching instructions, which only kept the css for a maximum of 10 minutes. Now, 100% of my static assets are cached for more than a week. This means return visitors will experience better performance.

What I learned

Wrapping it all up:

  1. Variable font support is approaching critical levels for wide adoption Almost all modern browsers support variable fonts, accounting for 79% of internet users.
  2. There are high-quality variable fonts that you can download and use today Nick Sherman has created a variable font repository if you’d like to browse and try what’s available.
  3. Variable fonts can improve performance if you subset carefully - While it’s not 100% out-of-the-box, there ar easy-to-use subsetting tools like glyphanger and fonttools that can help you over the finish line.

Next time you’re booting up a project, give variable fonts a try.

A note on fallback fonts

Astute readers will note that I chose not to implement fallback fonts for older browsers. The reason for this is twofold: first, I’m lazy. I wanted to ship this update without getting in the weeds. Second, I don’t care if my site doesn’t look identical in all browsers ever. I am confident that it’ll look good in whatever fonts match my detailed system font stacks.

Update: Safari 12 bug

When I originall published this post, I was experiencing a weird bug: in Safari, all instances of Inter were rendering in italic. No matter what I did, I couldn’t force Safari to use the normal (upright) version of Inter. I reached out for help:

My question was almost immediately answered by the creator of Inter, Rasmus Andersson:

And that’s exactly what I did: I replaced the single Inter font file with two files: one for the italic variant and one for the normal variant. As predicted, this fixed the bug. Hooray! Here’s the performance breakdown on a page that uses the same fonts as before (ie no italic sans-serif):

First Byte Start Render Requests Bytes In Speed Index
Typekit 0.21s 0.80s 8 80 KB 0.82s
Variable (subset) 0.21s (-0.2) 0.60s (-2) 6 (+82) 162 KB (-0.17) 0.65s
Variable (single-axis) 0.20s (-0.2) 0.60s (-2) 6 (+97) 179 KB (-0.22) 0.60s

I’m loading even more data than with the single-axis font (why? I honestly have no idea), but see a net decrease in speed index due to faster rendering. I’ll be exploring this in more detail in the future, but for now, it’s a great start.

Footnotes & References
  1. To say that variable fonts are new is slightly misleading. The concept of variable fonts has been around since the 1970’s, and the technology to implement variable fonts on the web is at least three years old. Until recently, browsers have been slow to support variable fonts. As of February 2019, however, 79% of internet users benefit from websitses that use variable fonts. ↩︎

  2. I used https://www.webpagetest.org/ for all of these measurements. Each result is the average of 3 runs. ↩︎