font-display: swap 能缓解字体加载闪动但不能确保加载完成,它仅控制渲染策略:先用后备字体显示,加载完再替换;需配合 document.fonts.load() 和 document.fonts.ready 才能准确获知字体就绪状态。

font-display: swap 能解决闪动,但不等于加载完成
很多人以为加了 font-display: swap 就万事大吉,其实它只控制渲染策略:字体没加载完时用 fallback 字体顶上,等加载成功再换过去。但它不提供“何时换完”的通知——你无法靠它知道 MyFont 究竟有没有真正就绪。
常见错误是把 DOMContentLoaded 或 window.onload 当作字体加载完成信号。这两个事件和字体无关:DOMContentLoaded 时字体文件可能还在下载中;window.onload 虽等资源,但对字体没专门保障,尤其在缓存失效或跨域字体场景下容易误判。
-
font-display: swap是视觉兜底,不是状态钩子 - 必须搭配
document.fonts.load()+document.fonts.ready才能拿到真实就绪信号 - 如果字体声明缺失(比如漏写
@font-face),load()会静默失败,不报错也不 reject
document.fonts.load() 必须传完整字体描述
document.fonts.load() 不是“查名字”,而是“触发并等待加载”。它需要你明确告诉浏览器:你要加载的是哪个字重、多大字号、用哪个字体族——否则它不知道该去匹配哪条 @font-face 规则。
比如你定义了 @font-face { font-family: "Inter"; font-weight: 500; src: url("inter-medium.woff2"); },那调用时就得写 document.fonts.load("500 16px 'Inter'"),不能只写 "Inter" 或 "16px Inter"。
立即学习“前端免费学习笔记(深入)”;
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 字体名必须带引号(如
'Inter'),且大小写敏感 - 字号可以是任意合理值(
16px、1rem都行),关键是让它能命中已声明的@font-face - 多个字体可链式调用:
document.fonts.load(...).then(() => document.fonts.load(...))
document.fonts.ready 返回 Promise,但只对已声明字体有效
document.fonts.ready 是一个 Promise,它会在所有已声明的 @font-face 加载完成后 resolve。但它不会主动触发加载——也就是说,如果你没先调用 load(),它可能永远不 resolve(尤其在字体尚未被 CSS 使用时)。
典型误用是直接 await document.fonts.ready,结果卡住。正确姿势是先 load() 触发,再等 ready 确认:
document.fonts.load("400 16px 'Inter'").then(() => {
return document.fonts.ready;
}).then(() => {
document.body.classList.add("fonts-loaded");
});
-
document.fonts.ready不接受参数,也不能链在未触发的load()后面 - 它只涵盖当前文档中已通过
@font-face声明的字体,动态插入的@font-face需要重新load() - 本地开发务必用 HTTP 服务(如
http://localhost),file://协议下document.fontsAPI 大概率不可用
fallback 字体选得不准,swap 也会出视觉跳变
font-display: swap 的前提是 fallback 字体和目标字体在度量上足够接近:x-height、ascender、descender、字宽不能差太多。否则即使布局不重排,文字也会“缩”或“撑”——比如用 sans-serif fallback 中文自定义字体,几乎必然跳。
检测方法很简单:打开开发者工具,禁用网络中的字体请求,看文字是否明显变形或换行;或者手动在样式面板里临时把 font-family 换成 fallback 值,对比渲染效果。
- 推荐 fallback 组合:中文用
"PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif - 英文优先选同族系系统字体(如 Inter → system-ui;Roboto → "Segoe UI", "Helvetica Neue"
- 避免用
monospace或serif作无差别 fallback,它们和现代 UI 字体度量差异极大
load() 参数写错却无报错——这三处最容易被忽略,但每处都会让字体加载检测失效。


















