@font-face 能用但路径错、格式漏、名字不一致会导致字体失效;font-family 和 src 是必需字段,须严格大小写匹配并加引号,src 路径以 CSS 文件为基准,推荐 woff2→woff→ttf 多格式 fallback,且 font-display: swap 可防 FOIT/FOUT。

@font-face 能用,但路径错、格式漏、名字不一致,字体就白配了。
font-family 和 src 是唯二必需字段
没 font-family,浏览器不知道怎么叫它;没 src,等于没告诉它字体在哪。其他属性全不写,也能加载基础字重正常体,但实际项目中几乎不可能只用一种样式。
-
font-family必须用英文单引号或双引号包裹,哪怕名字是纯英文(如'Inter'),否则遇到空格、连字符、中文名时必然失效 -
src至少提供一个有效路径,推荐按优先级顺序写多个 fallback:url('./fonts/my.woff2') format('woff2')→url('./fonts/my.woff') format('woff')→url('./fonts/my.ttf') format('truetype') -
format()的值必须和文件后缀严格对应:.woff2 对应'woff2',.ttf 对应'truetype',写成'ttf'或混用会触发 Safari/旧 Android 静默失败
src 格式顺序决定浏览器能否加载成功
浏览器对 @font-face 的 src 声明是按从左到右顺序尝试加载的,一旦某个格式成功解析就停止后续尝试。如果把兼容性差的格式(比如 woff2)放在最前面,而旧版 Safari 或 IE 不支持它,又没 fallback,字体就会直接失效成系统默认字体。
- 始终把
woff2放最前(现代浏览器压缩率高、加载快) - 紧跟
woff(IE9+、iOS 5.1+、Android 4.0+ 都支持) - 再放
truetype(.ttf,兼容老 Android 和部分桌面端,但无压缩) - 最后可选
svg(仅 iOS 早期版本需要,现在基本不用)
font-display: swap 是防止文字闪白的关键开关
不加 font-display,Chrome/Firefox 会阻塞文本渲染最多 3 秒(FOIT),等字体加载完才显示;设成 swap 后,立即用备用字体显示,等自定义字体就绪再替换(FOUT)。但若设成 block 且网络慢,用户可能看到长达 3 秒白屏。
立即学习“前端免费学习笔记(深入)”;
- 多数场景用
font-display: swap——平衡可读性与品牌一致性 - 对 logo 或标题字体要求极高时,可考虑
font-display: optional(字体加载超时即放弃) - 避免用
block,除非你明确接受 FOIT 行为 - 它必须写在
@font-face块内部,不能放到外部选择器里
本地开发时 font-face 路径 404 的常见原因
不是字体文件不存在,而是路径解析和服务器策略导致:
- Webpack/Vite 默认不处理
url()中相对路径,需配置asset或public目录 - 开发服务器(如 vite dev server)默认禁止跨域字体请求,需在
vite.config.js中加server.headers或启用cors - CSS 文件所在目录层级影响相对路径计算——
src的路径永远以 CSS 文件为基准,不是 HTML 或 JS 文件
最容易被忽略的是:字体文件本身有多个字重或斜体变体,但只声明了 font-weight: 400 和 font-style: normal,结果 strong 或 em 元素根本用不上你的字体——每个变体都得单独写一条 @font-face 块。


















