font-family recommendations
Draft: started • Tagged /css, /opinions
1. Never assume that a named font will work
There are no web-safe fonts; none are available across all major platforms.
Web fonts (@font-face and all) are not safe either:
- If not inlined, subresources can fail to load for all kinds of network reasons.
- Font loading is an area of concern for security, so some block it for safety.
- uBlock Origin has a dedicated button for disabling remote fonts.
- I think some browsers’ data-saving modes block fonts from loading.
(And those that don’t, should.)
Or the user might have elected not to let websites choose their own fonts.
I’ve been doing that since 2020, and it makes the web so much better.
For me, generic families are the only ones that will work.
One related JS thing: if you ever use document.fonts.load("1em my-web-font"),
remember that it’s fallible: the promise it returns may be rejected.
I came across about four things in the six years 2020–2025 that broke for this reason
(and two of them were in 2025).
Now for a couple of consequence of this.
I was actually going to write that last point as “always include a generic family”,
but really it’s only monospace that it’s important for. Still— b) Include serif or sans-serif if you want that kind of fallback font
Although serif or sans-serif are rarely important,
you probably want to include one of them all the same.
font-family: Arial, sans-serif;
font-family: Times New Roman, serif;
Otherwise, it’ll use the default font, which is probably serif but could be something else altogether.
2. Stop enumerating fonts that the system might have installed
I’ve seen too much of this kind of thing:
font-family: "Arial", Helvetica, 'Helvetica Neue', Liberation Sans, "Noto Sans", sans-serif;
Google Sans, Roboto, Arial, sans-serif
Definitely ditch Arial: it’s never going to be better than sans-serif. Also ditch Roboto: it’s almost never . It doesn’t help. sans-serif will resolve to a font no worse than those you named, and quite possibly better.
Here’s a real example I just came across (with spaces restored after punctuation, for it was minified):
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif
This is ridiculous, strictly worse than font-family: monospace, monospace. monospace will resolve to a font that is no worse.
Now I’m not saying there’s never a case for it.
Consider Georgia and Times New Roman, both serifs from Microsoft’s Core fonts for the Web.
But they have quite different character: Georgia is a good deal wider.
If that’s what you want for stylistic reasons, I will not begrudge you font-family: Georgia, serif. a) Have at most one named, non-web font
This is an exception
Consider Georgia and Times New Roman, both serifs from Microsoft’s Core fonts for the Web.
But they have quite different character: Georgia is a good deal wider.
If that’s what you want for stylistic reasons, I will not begrudge you font-family: Georgia, serif.
modernfontstacks.com is interesting. Their repository describes more about which fonts for which platforms. Interesting ideas, but I reckon it tries to prescribe beyond what is wise, and that a good chunk of the named fonts would be better removed. Also, they’ve wildly and catastrophically mishandled Courier New—looks like their images were made with the macOS Courier.
3. Strongly consider using only a generic family
So perhaps we’ve removed the locally-installed fonts as not useful;
now how about web fonts?
A web font is slower than no web font; and you can run into issues loading them; so we got font-display.
But really, instead of messing around with block and swap periods and redrawing and reflowing tradeoffs,
why not just use whatever font the user has?
It won’t be that bad. They might even have chosen fonts themselves.
Consider it. a) Yes, even for monospace
Historically, monospace defaults were bad.
This is mostly Microsoft’s fault for using that abomination Courier New,
which was digitised badly and is effectively a 200–250 weight instead of a 400.
Then, Apple introduced Menlo, and people liked it,
so people started putting that in their font stacks,
since the browser makers weren’t updating monospace.
And so it went on.
Well, those days have passed. Browser defaults are all better now.
They may not yet be spectacular in all cases, but they’re never bad any more.
So drop the Menlo, Monaco, Consolas, Bitstream Vera Sans Mono, Courier, Courier New, and try just leaving monospace.
Here’s a real declaration I just came across (with spaces added after punctuation; it was minified):
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif
If you ever deliberately put Courier New in a font stack, I’m not sure if we can be friends.
b) Actually, write monospace, monospace
Ugly bit of browser history which doesn’t seem to be documented in any spec I can find,
but everyone that old remembers.
If you use font-family: monospace; (explicitly or implicitly),
font-size will probably default to 81.25% instead of 100%.
(Users can change the generic fonts, the base font size, and the base monospace font size.)
If there’s a second family in the list, this doesn’t happen;
so font-family: my-web-font, monospace; is fine,
and font-family: monospace, monospace; is fine.
Or set the font-size manually, if you prefer.
If you’re using Lightning CSS, it will ruin monospace, monospace;
so for my part I’m writing monospace, m for now.
This only affects monospace. And maybe text that changes the language, but that’s different again.
I’d like to see if we can convince browser-makers to abandon the monospace size thing,
and increase it from the probably-13px to probably-16px.
I guess CSSWG would be the venue to suggest it.
4. Don’t use system-ui or ui-* for content
UI fonts are designed for short UI texts, not longform content.
UI fonts may not support your content language well: macOS is good about it,
but Windows is not, and you’ll end up with things like CJK users getting a bad monospaced font.
Sometimes, people have even deliberately chosen ridiculous system UI font—
quite common in some Android circles.
I presume system-ui will make content look ridiculous too.
w3c/csswg-drafts issue #3658 discusses some of the problems,
concluding that system-ui has been extensively abused.
mdn/content issue #41244 finally added a note to MDN discouraging its overuse.
These families have largely been used as a proxy for better default fonts. This is not a good use of them.
I believe system-ui was a mistake.
They should have left it at -apple-system and had BlinkMacSystemFont change to that:
no other platform had a useful equivalent concept at the time (though some do now),
and it was evident from well before the time of standardisation that
almost all use of this stuff was abuse working around the fact that
browsers weren’t updating their poorly-considered, ancient defaults for the existing generic families.
I believe that ui-serif, ui-sans-serif, ui-monospace and especially ui-rounded was an entirely stupid idea which should still be ripped out.
Especially given that they’re not expected to map to any font on… anything non-Apple.
Being Apple-only, they don’t need to be in the spec.
They can just expose them as fonts with names that just happen to start with -apple-.
(What, we’re not doing prefixes any more? This isn’t a prefix, just looks like one.)