系统字体栈:各平台字体体系详解

做跨平台字体适配,第一步得搞清楚——每个操作系统到底自带什么字体?

我刚开始做多端项目时,天真地以为「字体嘛,写个 font-family 就完事了」。结果在 Windows 上看着苹方渲染成宋体,在 Linux 上 Segoe UI 直接回退成点阵……嗯,那画面太美我不敢看。

说白了,系统字体栈就是你的「保底方案」。你写的 font-family 列表里,浏览器会从左到右依次查找,找到哪个用哪个。所以顺序很重要,选字更重要。

核心原则:先写最理想的字体,再写各平台回退字体,最后写通用字族(serif / sans-serif)兜底。

macOS / iOS 字体体系

苹果生态的字体策略很统一。从 iOS 9 和 macOS El Capitan 开始,系统全面转向了 San Francisco(SF Pro)和苹方。

  • 西文:SF Pro——苹果自家设计的无衬线字体,字怀开阔,数字和字母的辨识度极高。我个人特别喜欢它在小字号下的表现,比 Helvetica Neue 清晰不少。
  • 中文:苹方(PingFang SC)——取代了之前的华文细黑。苹方的字重分布更均匀,屏幕阅读时不容易发虚。
  • 旧版兼容:如果你的用户还有人在用 macOS 10.10 或 iOS 8,记得把 Helvetica Neue 和 STHeiti 也放进回退列表。

小技巧:SF Pro 在 macOS 上的字体名是 -apple-system,在 iOS 上也是。直接用这个关键字,系统会自动匹配当前版本的正确字体。

Windows 字体体系

Windows 这边就有点「历史包袱」了。Vista 时代引入的微软雅黑,到现在还是主力。但 Windows 11 开始,Segoe UI Variable 逐渐上位。

  • 西文:Segoe UI——从 Windows Vista 沿用至今。字面偏窄,适合英文界面。Windows 11 的 Segoe UI Variable 支持可变字重,更灵活。
  • 中文:微软雅黑(Microsoft YaHei)——屏幕渲染做了 hinting 优化,在低分辨率下比苹方更「锐」。但雅黑有个毛病:字距偏紧,长文本阅读容易累。
  • 旧版回退:Windows 7 以下没有雅黑,得用 SimSun(宋体)兜底。不过现在基本可以忽略这个场景了。

避坑提醒:我曾经在 Windows 上用过 Microsoft YaHei UI 这个字体名,结果部分 Win10 版本不识别。后来统一改成 Microsoft YaHei 才稳定。记住,别加 UI 后缀。

Linux 字体体系

Linux 桌面环境碎片化严重,字体策略也最复杂。但好在主流发行版基本都预装了 Noto 系列和文泉驿。

  • 西文:Noto Sans——Google 的「无豆腐块」计划产物。覆盖字符极广,字重丰富。我在 Ubuntu 和 Fedora 上都测试过,渲染效果很稳定。
  • 中文:文泉驿微米黑(WenQuanYi Micro Hei)——开源中文字体的标杆。虽然笔画细节不如苹方精致,但胜在免费且兼容性好。
  • 备选:部分发行版预装 Droid Sans Fallback,也可以作为回退选项。

个人经验:Linux 用户通常对字体比较敏感。我建议在 font-family 里把 Noto Sans 放在文泉驿前面,因为 Noto 的西文部分更现代,中文 fallback 机制也成熟。

Android 字体体系

Android 从 4.0 开始用 Roboto 作为西文默认字体,中文则依赖厂商定制。

  • 西文:Roboto——Google 为移动端设计的无衬线字体。字面宽、字怀大,触屏阅读友好。
  • 中文:思源黑体(Noto Sans CJK SC)——Android 6.0 之后原生支持。但国内厂商(华为、小米、OPPO)经常替换成自己的定制版字体。
  • 系统关键字:Android 支持 system-ui 和 sans-serif 作为回退。我个人习惯用 system-ui, sans-serif 兜底。

注意:Android 的字体渲染依赖 FreeType,和 macOS 的 Core Text 差异很大。同样的苹方字体,在 Android 上可能偏粗或偏窄。所以别指望跨平台「像素级一致」。

各平台字体对比一览

平台 西文默认 中文默认 系统关键字 注意事项
macOS / iOS SF Pro 苹方 (PingFang SC) -apple-system 旧系统需回退 Helvetica Neue
Windows Segoe UI 微软雅黑 Segoe UI Win11 新增 Variable 版本
Linux Noto Sans 文泉驿微米黑 sans-serif 发行版差异大,需多测试
Android Roboto 思源黑体 / 厂商定制 system-ui 厂商替换频繁,别硬编码

一个实用的跨平台字体栈

说了这么多,直接给个我目前在生产环境用的方案吧:

font-family:
  /* macOS / iOS */
  -apple-system, BlinkMacSystemFont,
  /* Windows */
  "Segoe UI", "Microsoft YaHei",
  /* Android */
  system-ui, Roboto,
  /* Linux */
  "Noto Sans", "WenQuanYi Micro Hei",
  /* 兜底 */
  sans-serif;

这个顺序的逻辑是:先走苹果生态的 -apple-system,再走 Windows 的 Segoe UI,然后 Android 的 system-ui,最后 Linux 的 Noto Sans。中文部分由各平台自己的默认字体自动 fallback。

为什么 BlinkMacSystemFont 要放在第二?——这是给 Chrome 在 macOS 上用的。不加它,Chrome 可能会用更老的 Lucida Grande 渲染西文,效果差一截。

知识体系总览

下面这张图帮你理清各平台字体体系的层级关系:

跨平台系统字体栈结构图 通用字族 sans-serif macOS / iOS Windows Linux Android SF Pro Segoe UI Noto Sans Roboto 苹方 PingFang SC 微软雅黑 文泉驿微米黑 思源黑体 / 定制 font-family: -apple-system, "Segoe UI", system-ui, "Noto Sans", sans-serif; 各平台字体通过 font-family 列表按序回退

这张图把四个平台的西文和中文默认字体都串起来了。你写 font-family 时,本质上就是在做「平台 → 西文 → 中文」的逐级映射。

避坑总结

最后分享几个我踩过的坑:

  • 别用字体全名:比如 PingFang SC Regular 在某些浏览器上不识别,用 PingFang SC 就好。
  • 中文引号不能省:字体名含空格或中文时,必须加引号。否则浏览器会解析失败。
  • 测试环境要全:我曾经只在 macOS 上测,上线后 Windows 用户反馈字体发虚。后来养成了「三系统截图对比」的习惯。
  • 可变字体慎用:Segoe UI Variable 虽然好,但旧版 Windows 不支持。如果你要兼容 Win10 以下,还是用静态版本吧。

重要:字体栈不是写一次就完事的。操作系统每年都在更新,字体策略也会变。我建议每半年重新审视一次你的 font-family 列表,看看有没有新的系统关键字或字体可以优化。