System Font Stack

Avatar of Geoff Graham
Geoff Graham on (Updated on )

Defaulting to the system font of a particular operating system can boost performance because the browser doesn’t have to download any font files, it’s using one it already had. That’s true of any “web safe” font, though. The beauty of “system” fonts is that it matches what the current OS uses, so it can be a comfortable look.

What are those system fonts? At the time of this writing, it breaks down as follows:

OS Version System Font
Mac OS X El Capitan San Francisco
Mac OS X Yosemite Helvetica Neue
Mac OS X Mavericks Lucida Grande
Windows Vista Segoe UI
Windows XP Tahoma
Windows 3.1 to ME Microsoft Sans Serif
Android Ice Cream Sandwich (4.0)+ Roboto
Android Cupcake (1.5) to Honeycomb (3.2.6) Droid Sans
Ubuntu All versions Ubuntu

Get to the snippet, already!

The reason for the preface is that it shows how deep you may need to go back to support system fonts. Additionally, it helps show that with new system versions, come new fonts, and thus the possibility of needing to update your font stack.

Method 1: System Fonts at the Element Level

Chrome and Safari have recently shipped “system-ui” which is a generic font family that can be used in place of “-apple-system” and “BlinkMacSystemFont” in the following examples. Hat tip to J.J. for the info.

One method for applying system fonts is by directly calling them on an element using the font-family property.

GitHub uses this method on their site, applying system fonts on the body element:

/* System Fonts as used by GitHub */
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";

Both Medium and the WordPress admin use a similar approach, with a slight variation, most notably support for Oxygen Sans (created for the GNU+Linux operating system) and Cantarell (created for the GNOME operating system). This snippet also drops support for certain types of emoji and symbols:

/* System Fonts as used by Medium and WordPress */
body {
  font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;

Note: This method should only be used on the font-family property instead of the font shorthand. published a thorough write-up on the warnings it generates due to the leading font appearing to be a vendor prefix.

Method 2: System Font Stacks

The limitation of the first method is that you have to call the full stack of fonts each time it’s used on an element and that can get cumbersome and bloat your code, depending on where and how it’s used.

Jonathan Neal offers an alternative method where system fonts are declared using @font-face.

The benefit here is that you can declare the fonts once and then that becomes the thing you can on the font-family property instead of the long list of fonts each and every time.

/* Define the "system" font family */
@font-face {
  font-family: system;
  font-style: normal;
  font-weight: 300;
  src: local(".SFNSText-Light"), local(".HelveticaNeueDeskInterface-Light"), local(".LucidaGrandeUI"), local("Ubuntu Light"), local("Segoe UI Light"), local("Roboto-Light"), local("DroidSans"), local("Tahoma");

/* Now, let's apply it on an element */
body {
  font-family: "system";

Note that Jonathan’s full example illustrates the capability to define variations of the system font family that was defined in the snippet above to account for italics, bolding, and additional weights.