font-display不是开箱即用的开关,必须写在@font-face内且配合format("woff2")、绝对路径、正确大小写和preload,否则旧版safari/edge会忽略规则导致foit。

font-display 不是跨浏览器开箱即用的开关,它在 Safari、旧 Edge、部分 WebView 下极易失效——根本原因不是值写错,而是浏览器压根没解析到这条规则。
@font-face 里漏了 format("woff2") 就等于没写 font-display
旧版 Safari 和 Edge 会直接忽略整条 @font-face 规则,退回到 auto 行为,导致 FOIT(文字空白)。Chrome 和 Firefox 虽能 fallback,但行为不一致,闪烁就出来了。
- 必须显式写
src: url("font.woff2") format("woff2"),不能只写url("font.woff2") - WOFF2 是唯一被所有现代浏览器稳定支持的格式;TTF/OTF 在 iOS 上解析慢,易延长闪烁窗口
- 路径别用相对地址(如
url(./fonts/icon.woff2)),file:// 协议或某些 WebView 下 404,规则静默失效
font-display 写错位置或拼错值,整个声明被丢弃
它只在 @font-face 块内生效,且对大小写、引号、冒号极其敏感。浏览器遇到语法错误会跳过整条规则,连 fallback 都没机会触发。
- ❌ 错误写法:
font-display: "swap"、font-display: swap:、font-display: swop - ✅ 正确写法:
font-display: swap(无引号、无冒号、全小写) - 别把它塞进
<link>标签、外层 CSS 或 JS 动态插入的样式里——统统无效 - 每个字重(
font-weight: 400、600、700)都要单独声明@font-face,并各自带上font-display
没配 preload 的 font-display 是纸面策略
font-display 控制“怎么显示”,preload 控制“什么时候开始加载”。不预加载,swap 的替换窗口在弱网下可能拖到 1.5 秒以上,用户已滚动半屏,字体才刚发起请求。
-
<link rel="preload" href="/fonts/inter-bold.woff2" as="font" type="font/woff2" crossorigin>——crossorigin必须加,否则跨域字体(CDN、SaaS 字体服务)预加载失败 -
as="font"不能写成as="style"或漏掉,否则降级为普通 fetch,失去高优先级 - 只 preload 首屏真正需要的字重,比如标题用 Bold,正文用 Regular;别全量 preload 中文字体
- preload 的
href必须和@font-face中src的路径**完全一致**(含查询参数,如?v=2)
iOS Safari 对 swap 的实现更激进,反而放大抖动
它对后备字体与 Web 字体的行高、基线计算差异更敏感,swap 后常出现文字上移/下移一帧,尤其在中英文混排或 flex 布局里。这不是 bug,是渲染引擎特性。
- 单纯设
font-display: swap无法解决度量差异;必须搭配font-size-adjust锁定 ex 比例,例如font-size-adjust: 0.5(需实测) - 关键容器要显式设
min-height、line-height,防止替换时重排 - 中文字体体积大(常超 2MB),
swap在弱网下极易变成“先闪再跳”,此时font-display: optional+ 子集字体(≤200KB)才是更稳的选择 - iOS Safari 15.4 之前根本不支持
font-display,回退到 FOIT 白屏——得靠@supports (font-display: swap)做降级兜底
真正卡住闪烁的,从来不是某个属性写没写对,而是从 @font-face 声明、格式、路径、preload 到 fallback 字体栈,整条链路上任何一个环节松动,都会让 font-display 失效。尤其是中文字体,子集化和布局锁定比属性本身更重要。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











