必须显式在@font-face内写font-display: swap,否则默认block导致首屏白屏1–3秒;需配合preload(带crossorigin)、woff2格式、format()声明及度量匹配的fallback字体。

不设 font-display 就等于默认 block,首屏文字大概率白屏 1–3 秒——这不是 bug,是浏览器在守规矩。
为什么 font-display 必须写在 @font-face 里
浏览器只认 @font-face 规则内部的 font-display,写在外部 class、style 属性、JS 的 element.style.fontDisplay 或 @supports 块里,全无效。常见错误包括:
- 把
font-display: swap加到body或字体类上,结果文字还是闪白 - 多个
@font-face共用同一个font-family名,但只给其中一个写了font-display,其余变体退回到默认block - 用
@import引入字体 CSS,却误以为它能控制加载行为——@import不带策略,浏览器照旧卡住等字体
swap 和 fallback 的实际区别在哪
swap 是立即用 fallback 渲染,字体加载完立刻替换;fallback 则只给约 100ms 加载窗口,超时就永久用 fallback,后续即使字体下载完成也不再替换。选哪个取决于你更在意什么:
- 选
swap:适合品牌正文,优先保证可读性,但要接受可能的布局跳动(FOUT) - 选
fallback:适合非关键文本(如侧边栏说明),追求视觉一致性,放弃字体出现的确定性 - 别用
block:等于主动制造 FOIT,毫无必要 - 慎用
optional:字体只在缓存命中或网络极快时才加载,适合装饰性标题,不适合正文
为什么写了 swap 还会跳、还会白屏
swap 解决的是“要不要等”,不是“换得稳不稳”。跳动和白屏往往来自三个被忽略的环节:
-
src漏写format("woff2"):浏览器无法预判字体类型,可能直接忽略整个@font-face规则,font-display也失效 - 没配
<link rel="preload" ... crossorigin>:字体请求等到 CSS 解析完才发起,弱网下 fallback 显示时间长达 1–2 秒,用户觉得“闪得久” - fallback 字体度量不匹配:比如用
"Times New Roman"配"Inter",字宽、x-height、line-gap 差异大,替换时段落高度突变
中文字体 fallback 推荐用 "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei";英文推荐 -apple-system, BlinkMacSystemFont, system-ui,避免泛称 sans-serif。
preload 字体必须带 crossorigin 吗
必须。哪怕字体同源,漏掉 crossorigin,浏览器会静默忽略该 <link rel="preload"> 请求——Network 面板里看不到失败提示,字体就根本不会提前下载。正确写法是:
<link rel="preload" href="inter-regular.woff2" as="font" type="font/woff2" crossorigin>
注意:as="font" 不能写成 as="style",type 要明确为 font/woff2,WOFF2 是当前唯一需上线的格式,TTF/OTF 在 iOS 上解析慢,会拉长 swap 窗口。
真正容易被忽略的点是:每个字重(regular / bold / italic)、每个变体都得单独声明 @font-face 并各自配 font-display 和 format();Google Fonts 链接必须手动加 &display=swap,否则返回的 CSS 里仍是 font-display: auto。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











