@font-face 不支持 CSS 自定义属性,因其为 CSS2.1 早期规则,而自定义属性 2016 年才标准化,两者解析器独立,src 值仅接受字面量或 url(),不参与变量替换。

--font-url 这类 CSS 变量不能用在 @font-face 的 src 里 —— 浏览器根本不解析,直接忽略整条 src 声明。
为什么 @font-face 不支持 CSS 自定义属性?
@font-face 是 CSS 中极早期的规则(CSS2.1 就已存在),而 CSS 自定义属性(--xxx)是 CSS Custom Properties for Cascading Variables Module Level 1(2016 年才成为正式推荐标准)。两者设计阶段相隔十多年,语法解析器完全独立:@font-face 的 src 值只接受字符串字面量或 url() 函数,不经过级联、不参与变量替换。
你写成这样:
@font-face {
font-family: 'MyFont';
src: url(var(--font-url)); /* ❌ 无效,浏览器当成非法 url() */
}等价于写了:
立即学习“前端免费学习笔记(深入)”;
src: url(); /* 空 URL → 解析失败 → 整个 @font-face 被丢弃 */
常见错误写法与实际表现
开发者常误以为变量能“注入”路径,结果字体完全不加载,Network 面板里根本看不到字体请求,控制台也无报错 —— 因为语法错误发生在 CSS 解析阶段,不是运行时错误。
-
src: url(var(--font-path) + '/myfont.woff2');→+在 CSS 里不是字符串拼接操作符,整条声明被跳过 -
src: url(calc(var(--base) + '/myfont.woff2'));→calc()不支持字符串拼接,且url()内部不接受calc() -
:root { --font-url: './fonts/roboto.woff2'; }+@font-face { src: url(var(--font-url)); }→ 变量值不会进入@font-face上下文
替代方案:预处理或构建时注入
真要动态管理字体路径,得在构建阶段解决,而不是靠运行时 CSS 变量:
- 用 PostCSS 插件(如
postcss-custom-properties)把变量内联为字面量,但注意:它只处理普通 CSS 属性,@font-face里的src默认不处理,需额外配置或改用postcss-font-magician - Webpack/Vite 中用
string-replace-loader或define替换占位符,例如把__FONT_PATH__替换成真实路径 - 服务端渲染时生成带具体路径的 CSS 片段,避免前端硬编码
纯前端静态项目,最稳妥的做法还是写死路径,或用 JS 动态创建 <style> 标签注入 @font-face(但要注意字体加载时机和 FOIT/FOUT 控制)。
容易被忽略的细节
即使你绕过变量、手写 url('./fonts/foo.woff2'),仍可能失败 —— 因为 url() 的路径是相对于 .css 文件位置,不是 HTML 页面;而很多人习惯按 HTML 目录结构去写,结果 404。这点比变量问题更隐蔽,也更常见。


















