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 they 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 |
---|---|---|
macOS | Monterey | San Francisco Pro (variable) |
macOS | El Capitan | San Francisco |
macOS | Yosemite | Helvetica Neue |
macOS | 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;
}
More recently, Chrome and Safari shipped a system-ui
, which is a generic font family that can replace -apple-system
and BlinkMacSystemFont
. That means the GitHub snippet could be reduced to this:
/* System Fonts with system-ui */
body {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
Note: Booking.com published a thorough write-up that warns against using the snippets that start with -apple-system
on the font
shorthand property because some browsers may view the leading font as a vendor prefix that will be ignored. Use the font-family
property instead, or replace -apple-system
and BlinkMacSystemFont
with system-ui
.
The obvious limitation here is that you have to call that long list of fonts each time you want to apply it to an individual element. Over time, that could become cumbersome and make your code more bloated than it ought to be. Instead, you might consider making a CSS variable for it:
:root {
--system-ui: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
.element {
font-family: var(--system-ui);
}
This is certainly easier to read but is also more maintainable if the stack ever needs updating. Change it once and it applies everwhere!
Method 2: System Font Stacks
Jonathan Neal offers an alternative method where system fonts are declared using @font-face
.
/* Define the "system" font family */
@font-face {
font-family: system-ui;
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-ui";
}
The snippet has not been updated in some time as of this writing and might result in different fonts, but the reason we’re including it here is that it illustrates the capability to define variations of the system-ui
font family that is defined in the snippet above to account for italics, bolding, and additional weights.
If we didn’t have CSS variables, this would be a much more effciient way to write and update the code.
Related
- OS Specific Fonts in CSS – which includes a JavaScript method for testing the font in use.
- System Fonts in SVG
- Implementing system fonts on Booking.com — A lesson learned – Booking.com shares how they learned using a system font stack on the
font
shorthand does not work as expected.
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.
Is there any OS that uses a serif for a system font?
Chris Coyier asked:
Chris, I could be wrong but I don’t think any OS or X11 desktop environment uses serif fonts as system fonts. However, my original comment could have been clearer. I was interested in using stacks of serif and monospace fonts that draw upon fonts that come pre-installed with various operating systems for use in bundled word processors like WordPad and terminal emulators like Terminal.app.
For example, Windows comes with Times New Roman and Courier New. OS X comes with Apple Garamond and Monaco. Prior to version 4.0, Android came with Droid Serif and Droid Mono in addition to the Droid Sans UI font.
Based on preliminary research I came up with the following “system” serif and monospace stacks. I’m pulling these out of my Sass variables partial.
These are only preliminary; I’m nowhere near done testing.
There is also one other thing to take into consideration when using system-font stacking;
Some metrics like ‘ex’ are based on the loading of the first font! This is important if you need your font to align with your grid.
Otherwise another font’s metrics are used, and you might be in for a surprise!
Where does that font name string come from:
.SFNSText-Light
? I dont see that name anywhere in the font definition file. Just curious, cheers!I believe that’s the private (system) font name used by the OS. It doesn’t show up in system or application font pickers, but it can be manually specified.
It’s San Francisco (New Sans?) by Apple and used as the System font on macOS
Using local fonts will use as much network (none) as e.g. sans-serif – why the second approach seems odd to me. If it’s about typing less I would use a SCSS variable – like:
Please correct me if I’m wrong :-)
you’re right.
Using the @font-face method works without SCSS.
Yes you do make a request to those fonts locally but you’re not faced with latency this way.
It’s worth noting that
system-ui
works in place ofBlinkMacSystemFont
in newer versions of Chrome.how about iOS?
Will it support any of these syntaxes?
Will it render using which font?
iOS uses San Francisco as the system font, just like OS X El Capitan. Does it render any differently for you on Mobile Safari than it does on desktop?
Booking.com wrote about their experience implementing system font stack, and warned against placing
-apple-system
first if you usefont
instead offont-family
.body {
font: 16px/1.2 BlinkMacSystemFont, -apple-system, “Segoe UI”, Roboto, Helvetica, Arial, sans-serif;
}
vs.
body {
font-family: -apple-system, BlinkMacSystemFont, “Segoe UI”, Roboto, Helvetica, Arial, sans-serif;
}
Maybe there could be an asterisk in here about that. Otherwise, very cool stuff!
Absolutely, good call! In fact, we published a link to the Booking.com post in another post and should have indicated it here as well. Consider this post updated!
Please excuse my ignorance, but what benefit is this over using
serif
orsans-serif
?Those don’t match the system font. For example, on my Mac, if I used
sans-serif
I’d get Helvetica, while the system font is San Francisco.Hi Ben, take a look at my comment below, and the link.
Thanks both, hadn’t realised that … will give it a try!
“-apple-system” and “BlinkMacSystemFont” are replaced by the new standard “system-ui” generic font family.
“system-ui” is also supported by Firefox.
See
https://www.chromestatus.com/feature/5640395337760768
system-ui
is not supported in Firefox 57.0.2 (64-bit) on Win7, but I can’t say for Win10Is there a similar stack for system monospace fonts? Fairly simple to get the correct font name for most non-Apple platforms, but it’d be nice to access SF Mono through a flag like -apple-system-monospace. So far there doesn’t seem to be any documentation about this.
Does this mean that if you don’t use the
font-face
stack as per Jonathan Neal’s approach, you’ll have to rely on your browser to “faux” bold and italic things?I started from scratch again recently, made an html page, and then realised how many fonts I’d need to upload for this page to be generally available… so I made a pdf. Maybe it’ll be useful to amateurs like me.
It’s a series of typefaces (sans, serif, humanist, mono) each with a few lines of identical sample text, arranged by increasing size. Take your pick: a site I’m working on has a column width of 540px, so that’s the line width used.
Scale it to 900% (don’t ask!) for an accurate rendition of the html on my 1920 x 1200 mac screen.
Even if the scaling isn’t reproducible, the relative sizes and strengths of the fonts can be gauged.
wavehands.net/some text examples.pdf
Cheers.
Seems IE11 can not recognize
-apple-system
infont-family
. IE11 considers that as an invalid value.Ugh. I am so burned out with Roboto.
A note, GitHub—and they’re still doing this—somehow got the order wrong. They’re using the generic
sans-serif
family in the middle of the stack which should make what follows pointless.Notice that what comes after
sans-serif
are emoji/symbol fonts – if the browser cannot display a character under sans serif, it’ll carry on to try these symbol fonts. Good for emoji.Do you really want the system font? I’m pretty sure most people actually just like to have a clean sans serif font like Segoe or SanFranciso. Or should your Chinese users really get a pixelated font? Should your Ubuntu users read the little quirky Ubuntu font? No? But that’s exactly their system font.
Maybe it’s better to choose a specific sans-serif, e.g. Open Sans, Source Sans Pro or Monserrat, that fits your tone and embed it as a webfont. If you can’t or don’t want to do this, then you may use this System Font Stack but better leave system-ui and other unwanted options out.
Also watch out for errors you get by using different fonts on different platforms. I collected some in my blog article – so better test extensively.
Which are the fonts for Windows 7, 8 and 10?
Am I the only one wondering why the recommended default fonts are even needed?
This is a great post! I think it would be really helpful to add the system font stack for monospace fonts as well.
I found the Chris Coyier comment from June 13, 2017 fascinating. So, for loading speed and consistency (user comfort), ‘serif’ or ‘sans serif’ are currently not good enough. It seems to me that this calls for an additional standard. Then if a particular OS or browser fails to display the proper font, it will simply be fixed in the next standards-compliant version. This would follow the same simplifying evolutionary path as we see happening at the tops of HTML5 Web pages and in character encoding.
The @font-face rule at the bottom of the post renders Tahoma for myself on Google Chrome 71 Windows 10
But what is the point of a system font stack, why not just use “font: sans-serif” and be done with it? Or upload a single sans-serif font to your webspace and use that if you want to maintain continuity or brand image.
There are some clear points:
In iOS 13, the system font stack setting would display Times New Roman.
To me it looks like the macos system font renders too tightly in Chrome, especially in smaller sizes. The characters are too close to each other. Is it just me?
One thing I’m confused about is that Apple publishes the San Francisco fonts for download on their website. In my design tool (Sketch app) I use SF Pro Text, but this font doesn’t seem to match
-apple-system, BlinkMacSystemFont
. They look different on macOS (I’ve tried both Chrome and Safari).I hate to install SF Pro Text on my website if I don’t need to, but it really bugs me that they don’t match. I want the version that you can see on http://www.apple.com
Is there something I’m missing?
That’s confused me, too! My thought is that SF Pro is different than SF Display, which is different from SF UI… the latter of which is the system font. At least, that’s my un-researched best guess.
Looks like “SF Pro Display is used for font size 20 pts or above whereas SF Pro Text is used for font size 19 pts and below. ” The system font dynamically switches between the two when the font size changes.
However, I’m seeing something very strange that the SF Pro Text that I downloaded from Apple looks like the SF Pro Display that I see in the browser and the SF Pro Display that I downloaded looks like the SF Pro Text that I see in the browser. It’s like they’re swapped. I can tell by the space between the letters. This is very odd.
Hi Stuart,
I just discovered this too on my site in Chrome and Safari on a Mac.
Did you find a solution, so that it actually shows the San Francisco Font ?
How about monospace version?
Simple
What is the scenario if some characters are not available in the first font, but available in the second?
Would the text be mixed from both fonts?
Yep.
Thanks! I have one issue.
Your article does not tell how I should use Segoe UI variable font in CSS in the system stack. You might know Microsoft introduced that font with Windows 11 but I don’t know how I can use that in the system stack to make my website look great on Windows 11 devices. Please guide.
No need to repeat them all everywhere or use @font-face. Just use CSS custom properties (“CSS variables”):
Then use that collection everywhere:
A bit caveat before you switch to
system-ui
:https://infinnie.github.io/blog/2017/systemui.html
This is an non-issue. That is the intended default behaviour in Chinese and should not be considered as a point anymore. See https://github.com/JLHwung/postcss-font-family-system-ui/issues/210#issuecomment-531519416 and https://github.com/primer/css/issues/1589#issuecomment-919985344 .
method 2 won’t support font-size-adjust. correct?
Does the article need to be updated to say that method 2 simply doesn’t work anymore? On macOS 12.5, for the given example I get Ubuntu Light in Firefox and Chrome, and Tahoma in Safari (because of Safari’s anti-fingerprinting ban on user-installed fonts). In other words, none of those system font names (starting with a dot) are being recognised at all.
Now, there’s really no need for method 2 if you just want to target the native system font, as
system-ui
handles that nicely these days. But if you want to specifically target the SF system fonts on Apple devices while falling back to something else on other systems, it looks like you’re still stuck with-apple-system, BlinkMacSystemFont, "Something Else"
. It’s a shame Chrome still refuses to recognise-apple-system
.Excellent notes, thanks!
Great post! Kudos