Using System Fonts

Using System Fonts

[2020 Update: A helpful reader emailed me and shared 70+ Best Free Fonts for Designers. It has lots of helpful design advice when picking fonts for your project, along with a plethora of font faces which are FREE of restriction for any use case. Thanks for the pointer Virgy!]

In my last post I promised some AWS Lambda experiments... I have been toying with a sample project that's hopefully more useful than your typical starter course to help explore Lambda together, but also spending a lot of time tweaking my personal website and this blog. Some times the OCD web designer personality takes a stronger hold than usual, particularly around holidays when I have time to spend tweaking and comparing options. I promise to share an interesting Lambda project as well as experiments with new(ish) Node.js frameworks (when compared to Express.js) in 2020. For now, I wanted to share thoughts on using system fonts in 2019 and beyond.

Why

To start, let's agree on a definition:

A system font is a font utilized by the operating system for displaying text used in menus, icons, errors, etc.

Like any choice in life, the decision to use (or ignore) system fonts comes with pros and cons. Let's start with the bad news... In my opinion at least, system fonts typically don't look as good as custom fonts. That is very subjective, but I think it is fair to say a limited set of system fonts can't give you the expressiveness available in the larger font universe. If you are building a brand where the style of the font face is integral or targeting physical mediums, you may (probably?) want a custom font. Context is important, and the context of this discussion is technical web content.

So why would you consider system fonts? Pros tend to boil down to two points... First, custom fonts are usually linked in your <head>. That's easy enough, but generates additional calls to remote resources when loading your site. That obviously slows things down, and is particularly bad for mobile users or those with slower Internet connections.

"I'll just serve my custom fonts locally," is the natural response. While well-intentioned, this leads to another problem. You'll end up with chained resource calls to your own server or CDN. How much this improves performance will depend on many factors, but at the end of the day it adds complexity (more moving parts for you to manage) and still isn't as optimal as it could be if we used system fonts.

So the choice to use a system font stack is often induced by a desire for better performance (in one deisgn nearly 2/3's of the time to first paint was retrieving web fonts!), but can also be considered an element of inclusive design. Since custom fonts typically assume fast Internet and reliable connectivity to served resources, it is at least worth considering what your content looks like when presented in system fonts (in an imperfect world, fallback to system fonts is more common than you might think). To be truly inclusive, we need to give some thought to default system fonts used by operating systems as well as around the web. This allows us not only to obtain a simpler, more performant design, but also one which is less visually jarring to the consumer.

Modern System Font Stack

The notion of using system fonts to improve performance and lend visual consistency to content is nothing new. Large web platforms have touted the concept for awhile. However, as times change default fonts also change. What worked great (or not so great) in 2010 can't be relied upon as status quo in 2020. When I decided to move from web fonts (they were so pretty, but I decided to optimize user experience over my own fickle fashion sense) to system fonts, I went looking for updated advice on what works well today.

As mentioned above, you'll minimally want to understand default fonts available on modern operating systems. What's changed since the last time I went down this road is the prevalence of mobile devices. While this spans a staggering number of physical devices, luckily we have a few key ecosystems: Apple, Windows and Linux (Android).

It's a couple years old now, but I found a thoughtful piece by CSS Tricks on using system fonts. It gives a good understanding of default fonts, as well as a couple different approaches to defining and using them on your site. They give examples from both GitHub and Medium. For any sites serving technical content, it's fair to say you have viewers who are used to the choices made by those platforms. One shortcoming is a focus on sans-serif (which I generally like for readability, so long as it's a modern variant and mixed with adequate letter-spacing and line-spacing). While that solves half the challenge, it's fair to say you will need at least a passing monospace variant if you want to share code samples.

I came across a slightly newer blog post focussed on solving the monospace conundrum. Rather than simply throwing out personal opinions (I can espouse and change opinions all day long!), I felt it shared a similarly mature approach to the CSS Tricks article – comparing available options to choices made by popular platforms. By considering GitHub (who doesn't see code shared on GitHub these days?) and Bootstrap's (still the most popular CSS framework) choices, and optimizing just a bit (removing less common options to ensure a more consistent experience), we have something decent that works for most folks.

Before reading on, be sure to check out the (short) posts linked above... They outline rationale for the choices, and also offer alternative implementations. Rather than reinvent that wheel, I'll simply share my current system font stack which combines a number of pieces from the original authors to provide a modern, performant, inclusive set of fonts suitable for use on technical sites:

@font-face {
  font-family: 'system';
  font-style: normal;
  font-weight: 400 700;
  src:
    system-ui,
    local("Segoe UI"),
    local("Roboto"),
    local("Helvetica"),
    local("Arial"),
    sans-serif,
    local("Apple Color Emoji"),
    local("Segoe UI Emoji"),
    local("Segoe UI Symbol");
}

@font-face {
  font-family: 'system-mono';
  font-style: normal;
  font-weight: 400 700;
  src:
    local("Consolas"),
    local("Menlo"),
    local("Courier"),
    monospace;
}
Define your preferred font stack with @font-face

You can use these easily when styling elements with font-family: system or font-family: system-mono. You won't have to clutter your code with font references, and future maintenance will be easier (I'm sure default operating system fonts and popular code sharing platforms will change again in our lifetime!).

This might not melt your users' eyes with the prettiest, most highly-customized, whiz-bang font face you can find... Okay, I guarantee it won't. However, the performance boost and more consistent user experience may be a worthy tradeoff. Who knows, your users might even thank you for getting to your content just a bit faster (after all, the content is what they're after, right?). If nothing else, the improved performance will get you better page rankings!