浏览器对@font-face的src按顺序匹配、命中即停,woff2应置首(Chrome/Firefox/Safari12.1+全支持),后接woff(iOS Safari11–12.1兜底)、ttf(极老安卓备用),错误顺序将导致静默回退系统字体。

font-face 的 src 顺序写错,字体根本不会加载
浏览器对 @font-face 中的 src 是“顺序匹配、命中即停”,不是“全试一遍”。如果你把 .woff2 放在最后,旧版 Safari(12 之前)、Android WebView 4.4–5.1 会跳过它,又没提供 .woff 或 .ttf,结果就是静默失败——控制台没报错,文字直接回退到系统字体。
现代项目推荐按兼容性从低到高排列,但别堆一堆冷门格式:
-
.woff2放最前(体积小、Chrome/Firefox/Safari 12.1+ 全支持) - 紧跟
.woff(iOS Safari 11–12.1、老 Android WebView 的刚需兜底) - 再加
.ttf(仅用于极老安卓或特殊 fallback 场景,别放.eot,IE8 已无实际维护价值)
错误写法:src: url('f.ttf') format('truetype'), url('f.woff2') format('woff2'); —— 多数浏览器根本不会读第二项。
font-family 名和实际调用不一致,等于白写
@font-face 里写的 font-family 是“注册名”,不是文件名,也不是路径。你写 font-family: 'MyFont',后面所有 CSS 里都得严格用 'MyFont'(带引号),哪怕只有一处写成 MyFont(无引号)或 myfont(大小写错),浏览器就认不出来。
立即学习“前端免费学习笔记(深入)”;
常见翻车点:
- 字体名含空格或连字符,比如
'Inter Var',漏掉引号 → 浏览器解析为两个独立关键字,直接忽略 - 同一字体多个字重(light / bold),用了同一个
font-family名但没配font-weight→ 所有字重都走默认normal,粗体变细体 - CSS 文件里注册了
'MyFont',HTML 中却写font-family: MyFont, sans-serif;(无引号)→ Firefox 会 fallback,Chrome 可能侥幸成功,但不可靠
不设 font-display,用户看到的是空白或闪动
默认 font-display: auto 在不同浏览器行为分裂严重:Chrome/Firefox 会阻塞文本渲染等字体下载(FOIT),用户盯着空白;Safari 则先上系统字体再替换(FOUT),文字“啪”一下跳变。这不是体验问题,是可感知的加载缺陷。
生产环境必须显式设置:
-
font-display: swap:最常用,立即用系统字体,加载完立刻换,无空白、无强闪 -
font-display: fallback:2 秒内未加载完就用系统字体,之后即使字体加载成功也不替换,适合非关键字体 -
font-display: block:短时空白可接受的品牌字体,比如 logo 文字,但正文慎用
iOS Safari 10–13.2 对 font-display 支持不完整,如果必须覆盖这些版本,得加 JS 检测:document.fonts.load('1em "MyFont"') 失败后动态切换 src 列表。
路径相对于 CSS 文件,不是 HTML 或根目录
@font-face 中的 url() 路径,解析基准永远是当前 CSS 文件所在位置,不是 HTML 页面,也不是域名根目录。很多人本地开发时路径碰巧对了,一部署到子目录或 CDN 就 404。
稳妥做法:
- 全部用相对路径,比如 CSS 在
/css/style.css,字体在/fonts/myfont.woff2,就写url('../fonts/myfont.woff2') - 避免用绝对路径
/fonts/...,除非你确定所有环境都部署在域名根下 - 构建工具(如 Webpack/Vite)中,字体文件被 hash 重命名,需确保 loader 正确处理
url()引用,否则打包后路径失效
验证方法很简单:打开浏览器开发者工具 → Network 标签页 → 过滤 woff2 → 看请求是否 200。404 就是路径错了,别猜,直接查 CSS 文件位置和 URL 对应关系。


















