Creating a System Serif Font Stack for Web Development

7 minutes to read · development · posted at 10:36 AM on 01/24/2017

Because I do web development at my day job, I try to keep up with the latest trends in web development. One of them is the use of system user interface (UI) fonts in CSS instead of downloading fonts.

I’d like to tell you a bit about this trend, because I’m rebuilding my personal website using Jekyll to get away from Squarespace, and that means I’ve got to come up with my own HTML and CSS.

What is the “system UI font stack”?

Ire Aderinokun describes and compares stacks used by WordPress, Medium, Ghost (not the band), and GitHub in “The New System Font Stack?”. Toward the end, she recommends using WordPress’ set, implemented as follows:

body {  
   font-family: -apple-system,  
                BlinkMacSystemFont,  
                "Segoe UI",  
                Roboto,  
                Oxygen-Sans,  
                Ubuntu,  
                Cantarell,  
                "Helvetica Neue",  
                sans-serif;  
}

I’ve extended this stack, borrowing from other stacks and adding Adobe’s “Source Sans” font. Like GitHub’s, my stack also supports emoji. :cat:

body {  
   font-family: -apple-system,  
                BlinkMacSystemFont,  
                "Segoe UI",  
                Roboto,  
                Oxygen,  
                Oxygen-Sans,  
                Ubuntu,  
                Cantarell,  
                "Fira Sans",  
                "Droid Sans",  
                "Helvetica Neue",  
                "Source Sans Pro",  
                sans-serif,  
                "Apple Color Emoji",  
                "Segoe UI Emoji",  
                "Segoe UI Symbol";  
}

Why use a system UI font stack?

This approach has a couple of advantages, which Ire Aderinokun explained in her article. I’ll paraphrase them below for your convenience:

Performance

Since system UI fonts are pre-installed, the page renders faster while making fewer HTTP requests. You want your pages to render fast if you’re serious about SEO.

Going Native

Because your website/web app uses the same fonts as your users’ operating systems, you’re providing an integrated user experience (UX). This is especially important for web apps, but can be handy for websites, too.

Fine-Grained Control

Rather than using the “font” shorthand property, setting the “font-family” property of the “body” element defines a set of possible fonts for all elements on the page. We’re still free to apply “font-style”, “font-variant”, “font-weight”, “font-size”, and “line-height” properties to various CSS selectors to style our text.

Drawbacks to using a system UI font stack

While I think it makes sense to use system fonts, this approach isn’t without its drawbacks. As Ire Aderinokun points out, maintenance can be an issue, and you might also run into naming conflicts. There’s another drawback Ms. Aderinokun doesn’t mention: they’re all sans-serif.

Naming conflicts

With the exception of “-apple-system” and “BlinkMacSystemFont”, current stack implementations specify fonts by name rather than by vendor-specific aliases. The “-apple-system” alias is defined by Apple, and allows Safari on OSX and iOS to use the San Francisco fonts. “BlinkMacSystemFont” is Google Chrome’s alias for these fonts.

If your user’s browser falls back on “Segoe UI” because your user is viewing the site on Windows, one of three things can happen:

  1. If “Segoe UI” is available, the web page gets rendered in Segoe UI.
  2. If “Segoe UI” isn’t available, the browser tries the next font in the stack.
  3. If the user’s “Segoe UI” is actually “Wingdings”, the page looks like shit.

The third possibility is the one you don’t want to happen. Also, don’t try to be clever and make “system” the first font in the stack. They already tried that at Medium, with amusing results.

Maintenance

Operating systems change, and part of that change involves changing the standard UI font. A few years ago, Microsoft changed the default Windows font from Tahoma to Segoe UI. More recently, Apple switched from Lucida Grande to San Francisco.

If web developers don’t keep up, their font stacks will go stale. Their sites might use fonts that don’t match their users’ operating systems. Hell, a site with an ancient font stack might even resort to the dreaded “sans-serif” alias.

While it shouldn’t be that difficult to update your stylesheets once or twice a year and push an update, that’s still time better spent on other things. Unfortunately, we’re stuck at the moment.

No Serif or Monospace Stacks for You

You may have noticed that all of the fonts in the various system UI font stacks are all sans-serif fonts. I noticed this myself, and submitted the following comment to CSS-Tricks’s article:

This makes a lot of sense and I plan to use this in my next website, but these are all sans-serif fonts. I can’t help but wonder if it’s possible to create similar stacks for system-default serif and monospace fonts. I might want to use the serif fonts on headings or blockquotes for emphasis, and apply monospace to the pre and code elements.

It might not be the worst comment ever posted (it isn’t abusive, racist, or sexist enough), but I’ve seen better. Hell, I’ve posted better — just not on a smartphone at four in the morning while taking a leak.

Here is Chris Coyier’s reply:

Is there any OS that uses a serif for a system font?

Mr. Coyier is right to ask this question. As far as I know, there isn’t a single OS or X11 desktop environment that uses serif fonts as UI fonts. However, I’ve never worked on a computer that didn’t come with at least one serif font pre-installed as part of the operating system or the operating system’s X Window System packages.

The same goes for monospace fonts. They’re only used in terminal emulators and the Windows command prompt, but every OS has at least one.

Next Steps for System Standard Font Stacks

The use of system UI font stacks is a relatively new trend, but I think it will continue because it makes sense. You can’t beat the performance, and it’s an excellent method for ensuring that your content remains readable regardless of device or browser.

However, system UI font stacks are currently a bit of a kludge. Fixing the drawbacks inherent in this approach will encourage wide-spread adoption…

Fix 1: Standardization

As system UI font stacks catch on, I hope web developers will lobby the World Wide Web Consortium (W3C) to update the CSS standard. Manually updating the font-family stack isn’t just only a burden on developers, albeit a relatively small one.

It’s also a performance hit users take with every page. Using current stacks, a browser must try fonts in sequence until it finds the first available font specified in the stack. In a worst-case scenario, a browser might attempt every font in the stack before resorting to “sans-serif”.

If the W3C updated the CSS spec to include a “system-ui-font” alias, web developers could instead specify “font-family: system-ui-font, sans-serif;” instead of trying to specify every reasonably common environment’s UI font by name/vendor alias in the right order. They could be confident that current browsers would use the operating system’s standard UI font. Browsers that don’t understand “system-ui-font” could still fall back on “sans-serif”.

Fix 2: Expansion from a System UI Font Stack to System Standard Font Stacks

The first fix solves the need for maintenance on the developers’ part and eliminates the risk of naming conflicts. However, the third drawback remains. While sans-serif fonts are better for low-resolution (100dpi or less) screens, displays with higher text resolution are becoming more common.

Apple led the way with their Retina displays on the iPhone, but small high-resolution displays are slowly becoming more common in laptops and desktops outside Apple’s ecosystem. If 4K or higher displays become sufficiently cheap and ubiquitous that 1080p replaces 1366x768 as the standard resolution for budget laptops, then improved HiDPI support may soon follow.

Once that happens, and text on screen gets rendered at resolutions approaching that of print, the readability edge that sans serif fonts enjoy over serif fonts may disappear. That doesn’t mean that operating systems will use serif fonts instead of sans serif for UI. Instead, designers may have the option of rendering long passages of text in serif rather than sans serif without sacrificing readability on screens.

That means that a system UI font stack like those currently in use isn’t enough. We need a set of System Standard Font Stacks (SSFS): one for sans serif, one for serif, and one for monospace.

Despite my previous focus on HiDPI displays, serif and monospace SSFSes can still be useful today. Maybe you just want to emphasize headings and blockquotes by using serif fonts instead of sans serif. If you make liberal use of the “code” and “pre” elements, you might want these to render in a monospace font. If you want to provide “printer-friendly” versions of your pages, perhaps you’d rather print with a serif text instead of sans serif.

Regardless of your reason for not wanting to use sans serif, having system standard font stacks in serif and monospace is still a good idea for the same reasons the original sans serif stack is trending: improved performance, better integration with the viewer’s device, and more creative control.

Basic Serif & Monospace System Standard Font Stacks

With these possibilities in mind, I did some research and came up with serif and monospace stacks composed of fonts that should be available on the widest possible variety of devices.

With the original system UI font stack’s example in mind, I’ve tried to arrange my stack from most specific to most generic. I doubt most Windows and Linux machines will have “Apple Garamond”, and that is likewise true for Android devices.

Serif SSFS

h1, h2, h3, h4, h5, h6, blockquote {  
   font-family: "Apple Garamond",  
                "Baskerville",  
                "Georgia",  
                "Times New Roman",  
                "Roboto Slab",  
                "Droid Serif",  
                "Times",  
                "Source Serif Pro",  
                serif,  
                "Apple Color Emoji",  
                "Segoe UI Emoji",  
                "Segoe UI Symbol";  
}

Monospace SSFS

pre, code {  
   font-family: "SF Mono",  
                "Monaco",  
                "Inconsolata",  
                "Fira Mono",  
                "Droid Sans Mono",  
                "Source Code Pro",  
                monospace;  
}

Notes and Caveats

The Source Serif and Source Code Pro fonts (along with Source Sans Pro) are freely available from Adobe Fonts on Github. I include them as a last stop before sans-serif, serif, and monospace in my stacks because I use these fonts on Linux.

Speaking of Linux, “Times” (as opposed to Times New Roman) is a font I used to see packaged with X11.

While Mozilla created Fira Mono to go with Fira Sans for Firefox OS, they didn’t bother to create a serif variant. Roboto Slab might be a reasonable substitute, but I have not been able to determine whether it comes pre-packaged with Android the way Roboto does.

I’ve included “Apple Color Emoji”, “Segoe UI Emoji”, “Segoe UI Symbol” in the serif stack so that text rendered in serif still has a chance of showing emoji on devices possessing these fonts. I also specify them in my sans serif stack.

Any Questions?

You’re welcome to use my serif and monospace system-standard font stacks in your own development if you like. If you have any questions, or want to contact me, you can reach me by email. If you decide to quote and link to this post in your own blog, I’d also like to hear from you.