HTML怎么解决字体不可见FOIT_HTML FOIT字体不可见解决方法手册

作者:袖梨 2026-06-14
FOIT是浏览器主动隐藏文本等待字体加载,而非单纯加载未完成;font-display: swap通过立即用系统字体渲染、加载完无感替换来解决FOIT,但需正确写入@font-face块内且避免404、CORS或体积过大等问题。

FOIT(Flash of Invisible Text)不是字体没加载完就卡白,而是浏览器主动把文字藏起来等字体就绪——它默认行为就是“宁可空白也不用系统字体凑合”。

为什么 font-display: swap 能解决 FOIT

现代浏览器在解析 @font-face 时,会根据 font-display 属性决定如何处理字体加载期间的文本渲染。默认值是 auto(等同于 block),即阻塞期 + 交换期都较长,导致文字长时间不可见。

  • font-display: swap 告诉浏览器:立刻用系统字体显示,等自定义字体加载完成再无感替换
  • 必须加在 @font-face 规则内部,不能写在 font-family 应用处
  • Chrome 87+、Firefox 73+、Safari 14.1+ 均支持;IE 完全不支持,但 IE 本就不触发 FOIT(它直接 fallback)

@font-face 中 font-display 的写法与常见错位

错误写法:font-display 放在外部选择器里,或漏掉分号,或拼错属性名:

@font-face {  font-family: 'Inter';  src: url('/fonts/inter.woff2') format('woff2');  font-weight: 400;  /* ❌ 错误:font-display 缺失 */}<p>/<em> ❌ 错误:写在 font-family 使用处 </em>/h1 {font-family: 'Inter', sans-serif;font-display: swap; /<em> 这个无效! </em>/}

正确写法(必须嵌入 @font-face 块中):

立即学习“前端免费学习笔记(深入)”;

@font-face {  font-family: 'Inter';  src: url('/fonts/inter.woff2') format('woff2');  font-weight: 400;  font-display: swap; /* ✅ 必须在这里 */}

swap 不生效的三个真实原因

即使写了 font-display: swap,仍可能看到 FOIT,常见实际原因:

  • 字体文件本身 404 或 CORS 报错,浏览器根本没开始加载,自然不会触发 swap —— 检查 Network 面板里 .woff2 请求状态码和控制台是否有 CORS policy 错误
  • 字体文件体积过大(> 200KB),加载耗时远超浏览器交换窗口(通常 3s),此时浏览器会放弃等待并保持 fallback 字体,但用户感知仍是“文字突然跳变”,而非“不可见”
  • CSS 文件被 rel="preload" 提前加载,但字体文件未预加载,造成字体资源滞后 —— 可对关键字体加 <link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>

font-display 其他取值的实际表现

除了 swap,还有几个值会影响 FOIT 行为,但多数场景不推荐:

  • block:最长阻塞期(~3s),之后才 fallback —— FOIT 最严重,仅适合 logo 字等极少数必须等自定义字体的场景
  • fallback:极短阻塞期(~100ms),之后立即 fallback,且后续加载完成也不替换 —— 文字永不跳变,但牺牲了品牌字体一致性
  • optional:只在字体缓存命中时使用,否则全程 fallback —— 适合低优先级装饰性字体,但对正文不适用

FOIT 的本质是权衡:swap 解决了“看不见”,但引入了“看得见却跳变”。真正难处理的,是字体加载失败后连 fallback 都不出现——那往往不是 font-display 的问题,而是路径、CORS 或声明语法错了。

相关文章

精彩推荐