font-family in CSS: choosing a font without ever breaking the display

font-family sets a ranked list of fonts, so text stays readable even when the ideal font is missing from the visitor's device.
5 min read
Believemy logo

A browser can only display text with one specific font at a time, and that font is not guaranteed to be installed on the visitor's device. The font-family property is CSS's answer to that problem: instead of forcing a single name, it accepts a list of candidates ranked by preference.

It shows up in almost every stylesheet, usually set once on body and passed down to the rest of the page through CSS inheritance. Getting it right avoids two common failures: a site that renders in an ugly default font, or worse, a site that renders in no intended font at all because the single name provided does not exist anywhere on the machine.


Definition

font-family takes a comma-separated list of font names. The browser tries the first name, and if it is not installed on the device (or loaded through a custom font), it moves to the next one, until it finds something available.

CSS
body {
  font-family: "Helvetica Neue", Arial, sans-serif;
}

Here, the browser looks for Helvetica Neue first. If it cannot find it, which is the case on most Windows machines, it tries Arial. And if even Arial were missing, the generic family sans-serif takes over: it does not name a specific font, it asks the system to supply its default font without serifs.


The fallback stack

This chain of candidates has a name: the fallback stack. The rule to remember is simple: it should always end with a generic family, never with a specific font name. Without that, a visitor who owns none of the listed fonts is left with the browser's raw default rendering, which varies from one system to another.

Generic familyWhat it asks the system for
serifA font with serifs, like Times New Roman
sans-serifA font without serifs, like Arial
monospaceA fixed-width font, for code
system-uiThe device's native interface font

A font name that contains a space, like "Helvetica Neue" or "Segoe UI", must be wrapped in quotes. Without them, CSS would read two separate words and the declaration would silently fail, with no error shown anywhere in the console.


System fonts

There is a separate family of fallback stacks made entirely of system fonts. The keyword system-ui requests the device's native interface font, the one used in its menus and buttons: San Francisco on macOS, Segoe UI on Windows, Roboto on Android. This choice has a concrete upside: those fonts already live on the device, so nothing needs to download, and the text appears on the very first paint, with no flash of unstyled text.

CSS
body {
  font-family:
    system-ui,
    -apple-system,
    "Segoe UI",
    Roboto,
    sans-serif;
}

This stack mixes several historical ways of aiming at the same target, because support for system-ui alone took a while to align across browsers. It is a common choice for an application interface, less so for a marketing site that wants a distinct brand identity.


The trap with a custom font

Writing font-family: "Poppins", sans-serif; is never enough to make Poppins appear if that font is not installed on the visitor's computer. font-family only names a candidate: it is the @font-face rule, or a link to a font provider, that must supply the actual file and attach it to that name.

Good to know

Forgetting @font-face triggers no visible error. The requested font is simply absent, the browser silently moves to the next candidate in the list, and the site renders in whatever fallback font comes next. The right move is to open the developer tools and check, in the network tab, that the font file actually loads.

Another trap involves font-weight: asking for a weight the loaded font does not provide sometimes produces a fake bold recreated by the browser, and sometimes produces nothing at all, depending on the browser. Explicitly loading the weights you actually use avoids that kind of surprise.


Best practices

Always plan for at least three levels: the font you want, one or two visually close substitutes, and a generic family as a last resort. Test the rendering with the custom font temporarily disabled, to see what a visitor on a slow connection will see. And remember that text size, controlled by font-size, does not make two fonts identical: two fonts set to the same point size can look very different in actual footprint. Our HTML and CSS course devotes a full section to loading fonts, from picking a provider to optimizing paint time.


Frequently asked questions

Question

What happens if none of the fonts in the list are available?

The browser falls back to its own internal default font, usually a fairly plain serif font. That is exactly why the list should always end with a generic family like sans-serif, which guarantees a consistent result even in the worst case.

Question

Do font names always need to be wrapped in quotes?

Quotes are required whenever the name contains a space, starts with a digit, or includes a special character. For a single-word name like Arial or Georgia, they are optional, but many teams add them everywhere for consistency and to avoid thinking about it case by case.

Question

Why does my Google Fonts font not show up even though the CSS looks correct?

The most common cause is a name that does not exactly match the one declared in the import link, a different space or letter case, or a font import placed after the rules that use it. Also check that the link to the font provider actually loads before the stylesheet that depends on it.

Question

Can a single page use several different font families?

Yes, nothing stops you from reserving one font for headings and another for body copy, by declaring two separate font-family rules on different selectors. It is actually a common design practice, as long as the total number of loaded fonts stays reasonable so it does not slow down loading time.

Related terms

Discover our hTML and CSS glossary

Browse the terms and definitions most commonly used in HTML and CSS development.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.