首要原因是@font-face的src路径错误,必须严格相对于CSS文件位置计算;format声明须与真实文件类型完全匹配(如.woff2→format('woff2'));加载成功但显示方块则多因font-family名不一致、类名版本错配或CSP拦截。

字体文件 404 或加载失败是首要原因
浏览器 Network 面板里看到 Failed to load resource: the server responded with a status of 404,基本可锁定问题在 @font-face 的 src 路径。路径错误不是“大概不对”,而是严格相对于 CSS 文件位置计算的——比如 CSS 在 /css/app.css,字体实际在 /fonts/icon.woff2,那必须写 url('../fonts/icon.woff2'),而不是 url('./fonts/icon.woff2') 或 url('/fonts/icon.woff2')(后者漏斜杠就变成相对 URL)。Vite/Webpack 构建后字体被挪到 /assets/xxx.woff2,但 CSS 里还留着原始路径,也会 404。
@font-face 中 format() 声明与真实文件类型不一致
这个坑很隐蔽:浏览器不校验文件内容,只按 format() 字符串决定是否加载。你给的是 .woff2 文件,却写成 format('woff'),旧版 Safari 和 IE 会直接跳过。必须严格对应:
-
.woff2→format('woff2') -
.woff→format('woff') -
.ttf→format('truetype') -
.eot→format('embedded-opentype')
现代项目建议至少提供 woff2 + woff 双格式 fallback,别只写一种。
字体加载成功但显示方块,大概率是 font-family 名称或使用方式错位
即使字体文件返回 200,元素上仍可能 fallback 到系统字体。常见情况包括:
立即学习“前端免费学习笔记(深入)”;
- HTML 元素写了
class="fa fa-user",但 CSS 里没引入 Font Awesome 的all.min.css,或引入顺序被其他样式覆盖 -
font-family声明漏了引号,写成font-family: Font Awesome 6 Free, sans-serif→ 浏览器把空格当分隔符,当成查找字族Font、Awesome、6…最终失败 - 用了 Font Awesome v6,却还在用 v5 的类名
fa fa-user;v6 必须配前缀,如fas fa-user(solid)或far fa-user(regular) - CSP 策略拦截了字体:控制台出现
Refused to load font错误,需检查服务器Content-Security-Policy头是否包含font-src白名单
跨域、MIME 类型和 font-display 设置影响实际渲染
字体资源跨域加载时,服务端必须返回 Access-Control-Allow-Origin: *,否则 Chrome/Firefox 会静默失败。同时,服务器要正确设置 MIME 类型:
-
.woff2→font/woff2 -
.woff→font/woff -
.ttf→font/ttf
另外,font-display: optional 在网络慢时会让浏览器直接跳过加载,改用 swap 可强制显示 fallback 再替换,方便快速验证是否真因加载延迟导致方块。
真正难排查的,往往是多个条件叠加:路径对了但 format 写错,字体加载了但 class 名版本不匹配,CSP 拦截了又没报错提示。建议固定一个调试顺序:Network 看状态码 → Elements 看 computed font-family → 控制台搜 Refused / CORS → 最后核对图标文档里的 class 名和 Unicode 映射。


















