关于字体加载策略的每一场讨论——预加载、子集化、font-display 调优——都发生在一个大多数团队从未有意识做出的决策的下游:到底要不要加载字体。对于一大类高性能应用来说,正确的字体选择就是用户机器上已经安装好的那一个。零千字节,零请求,零版面位移,首次绘制即可阅读。
如今"系统字体栈"意味着什么
我说的不是过去那种 Arial, sans-serif 式的敷衍。现代的系统字体栈是一次深思熟虑的编排:
font-family: ui-sans-serif, system-ui, -apple-system,
"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
这一条声明就为你换来:Apple 设备上的 San Francisco、Windows 上的 Segoe UI、Android 上的 Roboto——三款平台厂商累计投入数亿美元、专为自家屏幕打磨的字体,由最了解它们的渲染引擎完成微调和绘制。你的用户整天都在读它们;熟悉本身就是一种易读性特性,这一点《Universal Web》讲字体选择的章节有详尽论述。
衬线栈和等宽栈值得同样的用心:阅读界面用 ui-serif/Georgia/Charter,代码和数据用 ui-monospace/SF Mono/Consolas/"Cascadia Code"。本站自己的标题字体正是基于这套逻辑——有商业字体的人看到商业字体,其他所有人得到一条精心调校的后备链。
什么时候零才是正确的数字
这个决策取决于界面是什么。当产品是一件工具时,系统字体栈获胜:仪表盘、管理后台、交易与监控界面、开发者产品,任何每小时都要用、排印的职责是消失于无形的东西。在这些应用里,字体是纯粹的基础设施——没有人会欣赏凌晨三点呼叫自己的那个系统用的什么字体——性能预算更应该花在数据上。
当产品是一个场所时,品牌字体才配得上它的字节:营销页面、编辑性阅读,任何由排印承载身份认同的地方。这个作品集网站是有意加载 Web 字体的;它的排印就是内容本身。检验标准就在这里——如果删掉这款定制字体,产品是意义变少了,还是只是加载变快了?
把后备字体当正式字体来打磨
零千字节字体栈的功夫在于度量纪律。不同平台的字体有不同的 x字高和字宽,所以一个只在 macOS 上调校过的版面,到了 Windows 上呼吸节奏就会不同。三件工具可以弥合差距:
font-size-adjust归一后备字体的 x字高,让字体链中的每一款都以相同的有效字号呈现。text-wrap: balance和pretty吸收度量不兼容的字体之间的断行差异。- 在真实字体栈上测试——这是没人执行的纪律。把界面分别在 Segoe、SF 和 Roboto 下截图;如果设计只在其中一款下成立,那是设计错了。