font-display: swap是解决字体加载闪烁的底线配置,必须写在@font-face中、配合format("woff2")声明、preload预加载及度量相近的fallback字体,缺一不可。
直接加 font-display: swap 就能压住大部分字体加载闪烁,但不配 src 格式声明、不预加载、不选对 fallback 字体,照样会跳。
浏览器靠 format() 声明预估字体加载行为,如果漏写或写错,font-display 可能被忽略,退回到默认的 block 行为(即 FOIT 白屏约 3 秒)。
src 中必须显式标注格式,比如 url("inter.woff2") format("woff2"),不能只写 url("inter.woff2")
@font-face,并各自带 font-display
font-display,旧版 Safari 会直接无视——若需兼容,得搭配 document.fonts.load() 回退逻辑font-display: swap 的本质是「先用 fallback 渲染,再无感替换」,所谓“无感”取决于 fallback 和目标字体的度量是否接近。字号越大、行高越紧、字宽差异越明显,跳动越容易被肉眼捕捉。
"PingFang SC", "Hiragino Sans GB", "Microsoft YaHei" 这类系统级字体,避免用 "sans-serif" 这种泛称"system-ui", -apple-system, BlinkMacSystemFont 比 Helvetica 更稳,因前者是操作系统实际渲染链line-height 或 font-size 计算值和 Web 字体不一致,需用 CSS 显式锁定只设 swap 不预加载,字体资源仍要等 CSS 解析完才发起请求,弱网下 fallback 显示时间可能长达 1–2 秒——用户会觉得“闪得久”,不是不闪。
立即学习“前端免费学习笔记(深入)”;
<head> 里加预加载:<link rel="preload" href="inter.woff2" as="font" type="font/woff2" crossorigin>
crossorigin 属性不可省:WOFF2 字体跨域加载必须带它,否则 preload 失效,且后续 @font-face 可能报 CORS 错误font-display: fallback 给字体约 100ms 加载窗口,超时就永久用 fallback;optional 更激进,由浏览器决定是否加载——两者都杜绝了替换跳动,但也意味着你无法保证品牌字体一定出现。
fallback 适合图标字体(如 icon-font)、次要标题等非核心文本optional 适合装饰性大标题、动画字效等,移动端常直接跳过,别用在正文fallback 或 optional,即使字体后来缓存命中,也不会再触发替换——这点容易被忽略,以为“加载完还会换”真正难的不是写对 font-display,而是让 fallback 字体在宽度、x-height、字间距上足够贴近目标字体;否则 swap 再快,眼睛也会抓到那一帧跳动。