A Deeper Look at Generic Font Names in CSS

on | 1 Comment

If you’ve been writing CSS for some time, then you’ve certainly done something similar to the following, and likely multiple times in a single stylesheet:

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

The lone declaration in the rule set above is what’s commonly referred to as a font stack. This line defines the font that the browser should use for the specified element (in this case, for the <body> element). The stack is “Arial, Helvetica, sans-serif”. This instructs the browser to take the following steps:

  1. Look for a font called “Arial” defined in the CSS loaded on the page using @font-face, or on the user’s operating system. If that font is found, use it as the font for the specified element(s).
  2. If Arial is not found, look for a font called “Helvetica” in the same places. If it’s found, use it.
  3. If Helvetica is not found, use whatever font is defined as the default sans-serif font in the user’s browser or operating system.

That’s a pretty simplified version of what the browser does, but you can read the full font-matching algorithm in the spec if you feel like really delving into that sort of thing.

The final keyword used in that line of CSS is what’s referred to as a generic font family name. MDN’s article on font-family has a nice description of the generic family names and why they’re used:

Generic font families are a fallback mechanism, a means of preserving some of the style sheet author’s intent when none of the specified fonts are available. Generic family names are keywords and must not be quoted. A generic font family should be the last item in the list of font family names.

Most of you are probably pretty familiar with how that works, so nothing here so far has been groundbreaking to you. But there are some things that I think are worth noting about generic font names, some of which you might not be aware of.

Available Generic Family Names

A generic font family, according to the spec, can be defined using any of the following keywords:

  • serif
  • sans-serif
  • cursive
  • fantasy
  • monospace

The serif family is well known, but note what the spec says:

Serif fonts represent the formal text style for a script. This often means but is not limited to glyphs that have finishing strokes, flared or tapering ends, or have actual serifed endings (including slab serifs)

So the expectation here is more about the style of typeface being formal, rather than specifically having ‘serifs’, which is an interesting side point I hadn’t realized until I researched this article.

For sans-serif fonts, the spec says:

Glyphs in sans-serif fonts, as the term is used in CSS, are generally low contrast (vertical and horizontal stems have the close to the same thickness) and have stroke endings that are plain — without any flaring, cross stroke, or other ornamentation.

So in this case, there is an expectation that the font will lack serifs.

Monospace fonts have a simpler definition:

The sole criterion of a monospace font is that all glyphs have the same fixed width.

While those three family names are pretty common, you might not be too familiar with cursive and fantasy.

Regarding cursive, the spec says:

Glyphs in cursive fonts generally use a more informal script style, and the result looks more like handwritten pen or brush writing than printed letterwork.

So that’s good to keep in mind. If there’s a specific place where you’re using a fancy handwritten font, your font stack could potentially include cursive as the final entry, if you think the default cursive will fit as a decent fallback.

Similarly, fantasy is described as:

primarily decorative or expressive fonts that contain decorative or expressive representations of characters.

Some fantasy font examples are shown in the following image taken from the spec:

Examples of fantasy fonts

I appreciate knowing that fantasy and cursive exist as generic families, because I’ve always used serif and sans-serif as my generic fallback for most every font stack that wasn’t monospace. Of course, it might not always be correct to use these generic fonts if you’re not happy with the potential result, which I’ll discuss shortly.

Where Do Generic Fonts Come From?

Some CSS beginners, and even some experienced developers, might not understand exactly what is being defined when using one of the generic keywords in a font stack.

As you’re probably aware, the following CSS is perfectly valid:

body {
  font-family: monospace;
}

In the above code, I’m not using a stack; I’m telling the browser to use the generic monospace as the only font option. This is fine, though it’s far from ideal.

The monospace value doesn’t define some kind of built-in font that the browser has access to, but rather it points to a specific font on the user’s system. In fact, the browser has default settings for defining the generic font categories, and most of these can be changed in your browser.

In Chrome, the user can do this by going to Settings – Appearance – Customize Fonts. There the user will see the following options:

Choosing default generic fonts in Chrome

As you can see, Chrome allows the user to change the default font for three of the generic font categories: serif, sans-serif, and monospace (i.e. fixed-width). As the image shows, on my Windows machine I’ve changed my serif font to Georgia and monospace to Consolas.

Firefox has a similar option in its settings (Go to: Options – Language and Appearance – Fonts & Colors – Advanced):

Choosing default generic fonts in Firefox

Similar to Chrome, Firefox’s UI doesn’t allow you to change the default font for fantasy or cursive. However Firefox allows you to change either of these via about:config. You can access this by typing about:config in the address bar and accepting the weird ‘This might void your warranty!” message. Once you get to the config screen, you can search for the string font.name-list.cursive in the search bar, and you’ll see this:

Choosing the default generic cursive font in Firefox

Those values define the cursive font settings for different character sets. For English users, I believe the only one that needs to be changed is font.name-list.cursive.x-western. The user can set this value to the name of any valid font installed on the operating system. If the specified font is not found, the browser will resort to its default font (not a default cursive font, but just the default font).

According to one old post, Firefox used to have a setting in its config for defining the default fantasy font. But I don’t see a way to do that in the latest version of Firefox.

As for IE11 and Edge, the only way that I could see to change the default font in Edge is to go into the Internet Options setting in the Windows control panel. From there, you can make some browser-specific changes using the “Fonts” and “Accessibility” sections on the “General” tab. But I can’t see a way to change any of the generic font categories — not even serif, sans-serif, or monospace, which is a little annoying and just makes me even less likely to use one of those browsers.

One final thing I’ll mention in this section is that if you’re building Chrome extensions, you do have access to all the supported generic font keywords via the extensions API, as outlined in their docs. I’m not entirely sure exactly what you might do with that, but it’s there.

What are the Default Generic Fonts?

Depending on the OS the user is on, you’ll normally get some pretty standard and often undesirable options when using the generic keywords. Again, keep in mind that the generic keywords are only used if the first two or more fonts in the CSS font stack aren’t available, which is rare. So this is not normally a major concern.

Usually on a PC, the generic fonts might look like this:

  • serif – Times New Roman
  • sans-serif – Arial
  • monospace – Courier New
  • cursive – Comic Sans MS (yes, really)
  • fantasy – Impact
  • system-ui – Segoe UI

On my Mac machine, I have the following (you might get some different results):

  • serif – Times
  • sans-serif – Helvetica
  • monospace – Courier
  • cursive – Apple Chancery
  • fantasy – Papyrus
  • system-ui – .SF NS Text

As you can see, the fonts that these generic keywords point to by default aren’t great (especially on Windows). In fact, due to Comic Sans MS being the default cursive font on most Windows machines, I’d argue that it’s pretty questionable to ever use cursive as a generic keyword. Unfortunately, it seems that there aren’t many cursive fonts that are common to both Windows and Mac, so dealing with cursive-based font fallbacks isn’t easy. But again, it’s probably not a big deal as long as your primary font selection is reliable.

New Generic Font Names in CSS Fonts Level 4

Looking forward, CSS Fonts Module Level 4 introduces the following new additions to the generic font categories:

  • system-ui – The spec explains: “This generic font family is intended to let text render with the default user interface font on the platform on which the UA is running … The purpose of system-ui is to allow web content to integrate with the look and feel of a native app.” This one is now supported in WebKit browsers.
  • emoji – Intended for use with emoji characters. Firefox supports this keyword and you can define the default generic emoji font using font.name-list.emoji in the config.
  • math – Intended for use with mathematical expressions.
  • fangsong – Used for fang song typefaces in Chinese.

From what I could find in my research, only the first two have any support in major browsers, so most of these are probably not ready to be used.

Wrapping Up

This article went a little longer than I expected, but I hope some of it was useful to you. As I’ve mentioned multiple times, generic font names aren’t a big concern because they’re almost always a last resort.

But like any web development technique, it’s good to know the ins and outs of this specific CSS feature. If you have anything to add, let me know and I’ll update the article.

Web Tools Weekly

One Response

  1. Thanks Louis Lazaris, Do the all generic fonts load from PC?

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field. If you use keywords, your comment will be deleted, or your name will be replaced with the alias from your email address. No foul language, please. Thank you for cooperating.

Instructions for code snippets: Wrap inline code in <code> tags; wrap blocks of code in <pre> and <code> tags. When you want your HTML to display on the page in a code snippet inside of <code> tags, make sure you use &lt; and &gt; instead of < and >, otherwise your code will be eaten by pink unicorns.