font-display 是 css 中用于控制字体加载期间文本渲染行为的属性,而非字体加载开关;它需写在 @font-face 内部,取值如 swap、optional、fallback 等,影响空白期、回退时机与替换策略,配合 preload 时须注意加载顺序和 crossorigin 属性。

font-display 是什么,为什么不能只靠 @import
它不是字体加载的“开关”,而是告诉浏览器:当字体还没下载完时,怎么处理文字渲染。不设 font-display,Chrome 默认用 font-display: auto,实际行为接近 block(闪白+阻塞),用户可能看到空白或回退字体跳变。
常见错误是以为把 @import 放在 CSS 开头就“优化了”,其实没用——@import 本身不带加载策略,浏览器照旧卡住渲染等字体。
-
font-display: swap最常用:立即用系统字体显示,字体加载完再替换,无白屏但有布局偏移风险 -
font-display: optional适合非关键字体(如装饰性标题字):只在缓存命中时用,否则全程用回退字体 -
font-display: fallback折中:短时间 block(100ms),之后 fallback,再之后才 swap(如果字体后来加载完)
如何在 @font-face 中正确写 font-display
必须写在 @font-face 规则内部,且只能生效于该字体声明;不能写在外部 CSS 或 HTML <link> 标签里。
容易踩的坑:复制别人代码时漏掉引号、拼错值(比如写成 swop 或 swap:),导致整个 @font-face 被浏览器忽略——字体直接不加载,连 fallback 都没机会触发。
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-display: swap; /* 必须单独一行,无分号前缀,值不加引号 */
}
font-display 和 preload 搭配时的顺序陷阱
想让关键字体更快加载,常配合 <link rel="preload">。但顺序错了会失效:如果 <link rel="preload"> 在 <link rel="stylesheet"> 之后,浏览器可能已开始解析 CSS 并触发字体请求,preload 就白做了。
正确做法是 preload 标签必须出现在所有引用该字体的 CSS 加载之前,且 as="font" 和 type="font/woff2" 缺一不可,否则 Chrome 不会复用预加载资源。
- HTML 中
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>要放在<link rel="stylesheet">之前 -
crossorigin属性必须加:WOFF2 字体属于跨域资源,不加会导致 preload 失效(控制台报CORS policy错误) - 确保字体文件路径和
@font-face中的url()完全一致,包括大小写和斜杠方向
font-display 的兼容性和实测表现差异
Firefox 从 60+、Safari 从 11.1+、Chrome 从 60+ 支持,IE 完全不支持——这意味着设了 font-display 后 IE 会退回到默认行为(auto),但不会报错或崩坏。
真正容易被忽略的是字体加载完成后的重绘时机:即使用了 swap,如果字体文件过大(>100KB),替换过程仍可能卡顿,尤其低端安卓机上文字会“抖一下”。这不是 font-display 的问题,而是字体本身没做子集化或压缩。
- 用
fonttools或在线服务(如 Transfonter)生成仅含中文常用字的子集 WOFF2 - 避免在
@font-face中同时声明font-weight: 400, 500, 600多个字重却只用一个——每个 weight 都算独立字体,触发多次请求 - 检查 DevTools → Network → Filter “font”,确认是否真只加载了需要的格式(比如只传 woff2,别让浏览器降级请求 woff)
字体加载不是开个开关就完事的事,font-display 控制的是“怎么等”,但等什么、等多久,还是得看字体文件本身干不干净。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











