The system sans stack
Sans-serif · resolves differently per platform · rendering from your machine
Everything below is set in whatever your device resolved the stack to. On a Mac that is San Francisco; on Windows, Segoe UI; on Android, Roboto; on most Linux desktops, whatever fontconfig nominates. You are looking at exactly one of those, and which one it is changes the measurements.
Waterfall
Character set
Text, 14 / 17 / 20 px
The appeal is that the interface stops announcing itself as a web page and starts looking like part of the machine. The cost is that you have handed the typographic decisions to five different design teams who never agreed on x-height, and you will only find out where they disagree when a button label wraps on one platform and not on another.
The appeal is that the interface stops announcing itself as a web page and starts looking like part of the machine. The cost is that you have handed the typographic decisions to five different design teams who never agreed on x-height, and you will only find out where they disagree when a button label wraps on one platform and not on another.
The appeal is that the interface stops announcing itself as a web page and starts looking like part of the machine. The cost is that you have handed the typographic decisions to five different design teams who never agreed on x-height, and you will only find out where they disagree when a button label wraps on one platform and not on another.
Notes
This stack is not a typeface. It is a promise to use the local one, and the local ones differ in ways that matter for layout. San Francisco is narrower than Segoe UI at the same size and has a smaller apparent x-height; Roboto sits between them and is slightly tighter in the spacing. A line of interface text that fits comfortably on the machine you designed on can be one word longer somewhere else, which is how single-line labels acquire a second line in screenshots from users you cannot reproduce.
San Francisco has a second complication: it is optically sized. Apple ships separate designs for small and large text and switches between them at around 20 points. The large one is tighter and has finer detail. This is a genuine improvement and it is invisible until you try to match a mockup drawn at one size against a rendering at another, and the letterfit refuses to agree.
The keyword system-ui does the same job in one word and is now
broadly supported, but it has a well-known failure: on some systems it resolves
through the UI font configured for the current locale, which for a page in one
language displayed on a machine configured for another can produce a face with
the wrong metrics or a missing italic. The long explicit stack avoids that by
never asking the question.
Practical
| Resolves to | San Francisco (macOS, iOS) · Segoe UI (Windows) · Roboto (Android) · Cantarell, Ubuntu or DejaVu Sans (Linux, per distribution) |
|---|---|
| Cost | Zero bytes, zero requests, no flash of unstyled text |
| Weights | Reliable at 400 and 700. Intermediate weights exist on some platforms and not others — do not build hierarchy on 500 or 600 |
| Italic | Present everywhere, but synthesised rather than drawn on some Linux configurations |
| Comfortable at | 13–16px for interface text; less pleasant than a serif for long-form reading at any size |
| Watch for | Width drift between platforms. Test the longest label you actually ship, not a placeholder |
Stack used on this page
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
The order is historical rather than logical. -apple-system is
honoured by Safari and Firefox on macOS; BlinkMacSystemFont is the
same request for Chrome, which needed its own spelling. The named faces after
them are ordinary fallbacks, and Arial is there because it is the last thing that
is genuinely everywhere. Ending at the generic sans-serif keyword is
what makes the stack work on systems nobody anticipated.