字体系列推荐
Font-Family Recommendations

原始链接: https://chrismorgan.info/font-family

这份草稿反对在 CSS 中列出详尽且仅限本地字体的做法。由于网络、安全或用户自定义偏好等原因,Web 字体可能会加载失败,因此作者提倡采用“通用优先”的方法。 主要建议包括: * **简化字体栈:** 停止枚举数十种本地字体(如 Helvetica 或 Arial)。通用字体族(`sans-serif`、`serif`、`monospace`)通常会自动解析为高质量的系统默认字体。 * **优先使用通用等宽字体:** 始终包含 `monospace` 关键字,但需注意一个旧版浏览器的 Bug,即 `font-family: monospace` 可能会导致文字缩小。解决方法是使用 `font-family: monospace, monospace`(或添加一个占位字体)。 * **避免使用 UI 字体:** 作者认为 `system-ui` 和 `ui-*` 属性在很大程度上是误导性的,认为它们是为简短的界面文本而非长篇内容设计的,且已被开发者广泛滥用。 最终,作者建议 Web 开发者应更多地信任浏览器默认设置,避免使用臃肿且不可靠的字体栈,转而采用简洁、语义化的声明。

这个 Hacker News 讨论帖探讨了网页字体实现的复杂性。对话的核心是一篇博客文章,该文章建议使用通用字体族(等宽、衬线或无衬线字体),以确保在不同用户环境中获得一致的渲染效果。 评论者们就性能与用户体验之间的权衡展开了辩论。尽管开发者常被建议推迟加载或内嵌字体以提高页面加载速度指标,但有用户指出,字体在页面加载期间切换所导致的“布局偏移”令人沮丧。多位参与者表示,比起异步加载带来的技术优势,他们更倾向于优先保证稳定的视觉体验。此外,讨论还涉及了现代工具,有用户建议利用大语言模型生成代码,使自定义的视觉规格与用户的本地系统字体相匹配。
相关文章

原文

Draft: started Tagged ,

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.

a) Always include monospace if you want the text monospaced

I see this forgotten occasionally, since its lack doesn’t affect most people.
Sometimes on pages that were all-monospace for no good reason.
Those times, it honestly made the pages better! But other times it damages things.

As a concrete example, at the time of writing, Adel Faure’s ASCII might fly? artwork
is missing monospace, and looks a little like this for me:
(assuming your styles or user agent don’t make it monospaced!)

     .               .               .               .    
_.---._    .       .       .       .       .       .      
 . . . '-.   .   .   .   .   .   .   .   .   .   .   .   .
:.:.:.:.:.\.   .   .   .   .  __   .   .   .   .   .   .  
:.:.:.:.:.:'-.------------_.-'..'-.-----------------------
_:.:.:.:.:.:.:\--._____.-'.:.:.:.:.\-.__::::::::::::::::::
.'-.::.::.::.::'-._'-._____::..:.:.:.:'-:-.-..._:.__:.:.:.
-.-.\::.:::.::::::::::__::::(._____:.::.:::.::::'-.:=-.. .
.-.-.'--.___:.::::.:::::::(  '.--._''':.::::::::::::____.-
-.        -.'---.::::::::::'-. )::::::::::::_.-----'.-.-.-
.^.-.-.-.-.-.-.  \:::::::____TT_____.______'-.-.::.::.-._.
/ \::.:^:.:______.^-----/_-_ -_/\-.-/__/\__\::^:.^::.-..::
/ \   / \_/-_-_- /\\___/__/\/_/  \__|LL  LL|-/ \/ \(   ).^
._\..____/______/LL\___|LL__LL| /___/\   LL|_______(  ^ / 
 )__/____|LL  LL|LL|L L|LL||LL| |L L||--___/\______\./ \. 
/\__|____|LL__LL|_________===_______---/\___\LL__LL| / \ ^
||/\-_-_-\LL||L/____/____/\ /-_-_- /\\ ||______||LL|:/_\/ 
:/__\_____\___=|L L |L L ||/______/LL\ /_-_-_-/\ .::::|'/ 
-||||L L/____/\__==_______-|LL||LL|  |/______/  \i-i-i-i/_
7 - - --|L /\____\/\-_-_-_\==_""--""= |LL__LL|  |: : : :L|
pre {
	font-family: "jgs", monospace;
}

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.)

联系我们 contact @ memedata.com