Type something to search...
What are system font stacks and when should you use them?

What are system font stacks and when should you use them?

A system font stack is a CSS font-family list that tells the browser to use the fonts already installed on the visitor's operating system, usually the same interface font the OS uses for its own menus and dialogs. On a Mac or iPhone that means San Francisco, on Windows it means Segoe UI, on Android and ChromeOS it means Roboto, and on Linux it depends on the desktop. Because nothing is downloaded, text renders immediately with no flash, no layout shift and no extra requests. The modern way to write one starts with the generic system-ui keyword and falls back to named fonts for older browsers. You should use a system stack when speed, a native feel and zero maintenance matter more than a distinctive typographic identity.

Fonts are one of the heaviest and most fragile parts of a page's loading path, and a system stack removes that problem entirely. The trade-off is that your site looks slightly different on every platform and you give up control over the exact letterforms. In this article you'll learn how system font stacks work, what each keyword and font name does, how to write sans-serif, serif and monospace stacks, the pitfalls to watch for, and how to decide whether a native stack or a custom web font is right for your project.

How a System Font Stack Works

Every font-family declaration is a priority list. The browser walks through it from left to right and uses the first font that is available on the device and contains the character it needs to draw. A system stack exploits this by listing the native UI fonts of each major platform, so each device stops at its own font.

A minimal modern stack looks like this:

body {
  font-family: system-ui, sans-serif;
}

system-ui is a generic family defined in CSS Fonts Level 4. It maps to whatever the platform considers its default user interface font. The trailing sans-serif is a safety net for any browser that doesn't understand system-ui.

Because the browser resolves fonts per character, the stack also matters for symbols and scripts your main font doesn't cover. If San Francisco has no glyph for a particular character, the browser carries on down the list, and eventually falls back to its own system-wide font fallback.

What Each Platform Uses

The fonts behind system-ui differ by operating system and sometimes by version and language:

PlatformDefault UI fontNotes
macOS, iOS, iPadOSSan Francisco (SF Pro)Not available by name; reached through system-ui or -apple-system
Windows 10 and 11Segoe UISegoe UI Variable is used by the Windows 11 shell
AndroidRobotoSome manufacturers ship their own UI font
ChromeOSRobotoAlso available on many Linux systems
Linux desktopsVariesOften Cantarell (GNOME), Ubuntu, Noto Sans or DejaVu Sans

Apple deliberately doesn't expose San Francisco as a normal named font in browsers, so writing font-family: "SF Pro Text" won't work for most visitors. You have to reach it through a keyword.

The Keywords Explained

Several keywords and legacy names appear in popular stacks. Knowing what each one does helps you trim the list to what you actually need.

system-ui

The standard generic family for the platform UI font. It's supported by all current major browsers, so it should come first in a modern stack.

-apple-system and BlinkMacSystemFont

These are older, non-standard names that map to San Francisco. -apple-system was Safari's and Firefox's way in, and BlinkMacSystemFont was Chrome's on macOS. Current browsers understand system-ui, so these only help visitors on quite old browser versions. Many teams still keep them because they cost nothing.

The ui- Keywords

CSS Fonts Level 4 also defines ui-sans-serif, ui-serif, ui-monospace and ui-rounded. They let you ask for the system's own serif, monospace or rounded design. On Apple platforms Safari maps them to SF Pro, New York, SF Mono and SF Pro Rounded. Support outside Safari is limited, so always follow them with named fonts and a generic family.

Generic Families

sans-serif, serif and monospace should always end a stack. They guarantee the browser has something sensible to fall back to, even if none of the named fonts exist.

Writing a Complete Sans-Serif Stack

A robust stack covers the keyword, legacy Apple names, the main platform fonts, a couple of widely installed fallbacks and the colour emoji fonts:

:root {
  --font-system:
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    Roboto,
    "Noto Sans",
    "Helvetica Neue",
    Arial,
    sans-serif,
    "Apple Color Emoji",
    "Segoe UI Emoji",
    "Segoe UI Symbol",
    "Noto Color Emoji";
}

body {
  font-family: var(--font-system);
}

A few details are worth calling out:

  • Quote names with spaces: "Segoe UI" and "Helvetica Neue" need quotes. Keywords such as system-ui and sans-serif must not be quoted, or the browser will look for a font literally called "system-ui".
  • Emoji after the generic family: Placing the emoji fonts at the end means they're only used for characters the text fonts can't draw. Some text fonts include monochrome versions of a few symbols, so listing emoji fonts earlier can change how ordinary characters such as digits or the hash sign look.
  • One custom property: Defining the stack once and reusing it keeps headings, buttons and form controls consistent.

Form controls deserve a special mention. Browsers don't inherit fonts into button, input, select and textarea by default, so add a reset:

button,
input,
select,
textarea {
  font: inherit;
}

Serif and Monospace System Stacks

System stacks aren't limited to sans-serif text. Operating systems ship good serif and monospace fonts too.

A serif stack for long-form reading might look like this:

.article {
  font-family:
    ui-serif,
    "Iowan Old Style",
    "Palatino Linotype",
    Palatino,
    Georgia,
    Cambria,
    "Times New Roman",
    serif;
}

Iowan Old Style ships with Apple platforms, Palatino Linotype and Cambria with Windows, and Georgia is available almost everywhere on desktop.

A monospace stack for code is one of the most common uses of system fonts, because downloading a code font just for a few snippets is rarely worth it:

code,
kbd,
pre,
samp {
  font-family:
    ui-monospace,
    SFMono-Regular,
    "SF Mono",
    Menlo,
    Consolas,
    "Liberation Mono",
    monospace;
  font-size: 0.9em;
}

Menlo is present on macOS, Consolas on Windows, and Liberation Mono on many Linux systems. The slightly reduced size compensates for monospace fonts usually looking larger than the surrounding text.

Pitfalls to Watch For

System stacks are simple, but a few behaviours catch people out.

Language and Locale Differences

system-ui resolves to the platform's UI font for the user's language settings. On a Windows machine set to Chinese, Japanese or Korean, it may pick a CJK UI font whose Latin letters look quite different from Segoe UI. That's correct behaviour for those users' interfaces, but it can surprise designers testing an English site. If you need consistent Latin letterforms across locales, list "Segoe UI" explicitly before or instead of system-ui and test with different system languages.

Metrics Vary Between Platforms

San Francisco, Segoe UI and Roboto have different widths, x-heights and vertical metrics. A button label that fits neatly on a Mac might wrap on Android. Design with some slack:

  • Avoid fixed widths for text containers: Let buttons, badges and tabs size to their content.
  • Use unitless line height: A value such as line-height: 1.5 scales with each font rather than locking in a pixel height.
  • Test on real devices: Check at least macOS or iOS, Windows and Android before shipping.

Weights Aren't Guaranteed

San Francisco and Segoe UI Variable offer a wide weight range, but some Linux fonts only ship regular and bold. If your design relies on a 300 or 600 weight, some visitors will see the nearest available weight instead. Keep your hierarchy readable with only 400 and 700.

Don't Reference Fonts You Can't Rely On

Listing a long chain of obscure fonts makes a stack harder to reason about without helping many users. Each name should earn its place by covering a real platform.

System Stacks Versus Custom Web Fonts

The decision usually comes down to what the typography needs to do.

FactorSystem font stackCustom web font
Download costNoneUsually tens of kilobytes per style
Render delayNonePossible FOUT or FOIT while loading
Layout shift from fontsNonePossible unless managed carefully
Brand distinctivenessLow; looks nativeHigh; same letterforms everywhere
Cross-platform consistencyVaries by OSConsistent
LicensingNothing to manageMust check the licence
MaintenanceMinimalFiles, formats, preloads, updates

When a System Stack Is the Right Choice

  • Web apps and dashboards: Interfaces that should feel like part of the operating system benefit from the native UI font, and users spend their time on content and controls rather than letterforms.
  • Documentation and internal tools: Readability and speed matter more than personality.
  • Performance-critical pages: Landing pages for slow networks, emerging markets or strict Core Web Vitals budgets.
  • Code blocks and secondary text: Even sites with a custom brand font can use a system monospace stack for code and a system stack for small UI text.

When a Custom Font Is Worth It

  • Brand-led sites: Where the typeface is part of the identity and must look the same everywhere.
  • Editorial design: Magazines and long-form publications where typographic voice is a large part of the reading experience.
  • Specific language or feature needs: When you need OpenType features, scripts or weights that system fonts don't reliably provide.

A popular middle ground is to use a custom font only for headings and keep body text on a system stack. Headings are short, so one or two font files cover them, and body text renders immediately. If you go down the custom route, read up on how web fonts affect page speed first.

Using a System Stack as a Fallback

Even if you load a custom font, your fallback list is effectively a system stack. It's what visitors see while the web font loads, if it fails, or if they've blocked downloadable fonts. Choosing native fonts with similar proportions to your web font reduces the visible jump when the custom font arrives:

body {
  font-family:
    "Brand Sans",
    system-ui,
    "Segoe UI",
    Roboto,
    Arial,
    sans-serif;
}

You can go further and tune the fallback's metrics to match the web font with size-adjust and related descriptors, which is covered in the guide to preventing layout shift from web fonts.

Testing Which Font Is Actually Used

The CSS only states a preference, so check what the browser chose:

  1. Open your page in Chrome or Edge and inspect a text element.
  2. In the Elements panel, switch to the Computed tab.
  3. Scroll to the bottom to see Rendered Fonts, which lists the actual font and how many glyphs it drew.

Firefox shows the same information in the Fonts tab of its Inspector, and Safari's Web Inspector shows it under the Font section of the details sidebar. Checking on each platform confirms your stack resolves the way you expect.


FAQ: System Font Stacks

It's supported by all current major browsers, but adding a generic family such as sans-serif after it costs nothing and protects older browsers. Many teams also keep -apple-system and Segoe UI for extra coverage.

Not by name and not by downloading it. Apple's licence restricts San Francisco to use on Apple platforms, and browsers only expose it through system-ui or -apple-system on Apple devices.

They remove font downloads from the loading path, so there's no font-related render delay or layout shift. That can help Largest Contentful Paint and Cumulative Layout Shift, although other factors usually matter more.

Because each platform resolves the stack to its own font: Segoe UI on Windows and San Francisco on Apple devices. Different widths and x-heights are expected, so design layouts that tolerate small changes in text size.

Listing Apple Color Emoji, Segoe UI Emoji and Noto Color Emoji at the end of the stack helps make emoji render in colour consistently. Put them after the generic family so they don't override normal characters.

They're designed for interface legibility at small sizes and are familiar to users, which makes them a good accessible choice. Accessibility still depends on size, contrast, line height and line length, not just the font.


Conclusion

A system font stack hands typography back to the operating system: San Francisco on Apple devices, Segoe UI on Windows, Roboto on Android and a native font on Linux. Start with system-ui, add the named platform fonts, end with a generic family and emoji fonts, and you get instant rendering with no downloads, no layout shift and nothing to license or maintain.

Use a system stack when your site is an application, a tool or a performance-sensitive page, and reach for a custom web font when brand identity or editorial voice depends on specific letterforms. Either way, write your fallback list as carefully as your primary font, because every visitor sees it at some point.

Share :

Related Posts

How to make typography accessible?

How to make typography accessible?

You make typography accessible by choosing clear typefaces, setting text in relative units so it scales with user preferences, giving it enough colou

Dive Deeper
What are the parts of a letterform?

What are the parts of a letterform?

A letterform is the shape of a single letter, and typographers break it down into named parts. The main ones are the stem (the main vertical

Dive Deeper
What are ascenders, descenders and the baseline?

What are ascenders, descenders and the baseline?

The baseline is the invisible line that letters sit on. Ascenders are the parts of lowercase letters that rise above the x-height, such as th

Dive Deeper