font-display需与@font-face、preload、font-family回退链及size-adjust协同生效,单独设置易失效:漏format、路径错误、拼写错误或未在@font-face内声明均导致规则被忽略,fallback需preload配合才能在500ms窗口内触发,swap需size-adjust抑制布局抖动。

font-display 不是“开了就完事”的开关,它必须和 @font-face、preload、font-family 回退链、size-adjust 一起配齐,否则 swap 会闪、fallback 会失效、optional 会直接不加载。
font-display: swap 为什么写了还在闪?
写了 font-display: swap 却仍有明显跳动,大概率不是值的问题,而是整条 @font-face 被浏览器忽略了:
-
src中漏了format("woff2")—— Safari 和旧 Edge 直接跳过规则,退回到auto行为(即 FOIT 白屏) - 字体路径是相对地址(如
url(./fonts/inter.woff2)),在 WebView 或本地file://环境下 404,规则静默失效 -
font-display写在<link>标签或外层 CSS 里 —— 它只在@font-face块内部生效 - 拼写错误:写成
swop、swap:或"swap",整条规则被丢弃
font-display: fallback 在移动端更稳,但有硬性前提
font-display: fallback 是多数响应式页面的合理起点,但它不是加了就自动生效:
- 必须搭配
<link rel="preload" as="font" crossorigin>,否则字体请求可能在 500ms 窗口过后才发起,用户已滚动走 - 每个字重(
400、700、600)要单独写@font-face并声明font-display: fallback,不能共用一个font-family名却只给其中某个加 - 中文字体体积大(常 ≥2MB),
fallback的 500ms 窗口比swap的“无限等待”更可控,尤其在 iOS Safari 下表现一致
swap 导致布局抖动?size-adjust 才是关键解法
font-display: swap 解决白屏,但解决不了文字“突然变高/变矮”的抖动——这是回退字体与自定义字体的 x-height、line-height、字宽不一致导致的重排(CLS):
- 必须搭配
font-family回退链,例如font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif,避免 Android fallback 到过粗的Droid Sans -
size-adjust微调占位尺寸,值通常在95%~105%之间,需实测;它只在 Chromium 和 Safari 17.4+ 生效,且必须和font-display: swap共存才起作用 - 在 Chrome DevTools 的 Rendering 面板勾选
Layout Shift Regions,刷新看红框是否减弱,才是验证是否生效的唯一方式
optional 不是“防闪烁”,是“放弃加载”
font-display: optional 的本质是:浏览器预估加载时间 >100ms 就直接跳过请求,全程用系统字体。它不防闪烁,而是让闪烁根本没机会发生:
- 只适合非关键内容,比如装饰性 banner 文字、icon font、次要标题
- Safari 14.1 之前版本不支持,会退化为
block,导致 iPad mini(A12 + iOS 15)白屏 - 必须用
@supports (font-display: optional)包裹,否则老浏览器直接忽略整条规则
最容易被忽略的点是:font-display 控制“怎么显示”,preload 控制“什么时候开始加载”。两者缺一不可,而 size-adjust 和 font-family 回退链才是真正压制抖动的底层动作——它们不在文档开头显眼位置,但决定了用户是否真的“看不见跳动”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











