Tailwind CSS 自定义字体生产环境加载失败,根本原因是 @font-face 与 tailwind.config.js 配置不一致:声明须置于 CSS 入口顶部且在 @tailwind base 前;font-family 字符串必须字面量完全一致(大小写、引号、空格);url 路径须相对 CSS 文件且走 HTTP 服务;配置必须用 extend.fontFamily 而非直接覆写。

Tailwind CSS 自定义字体在生产环境加载失败,几乎总是因为 @font-face 和 tailwind.config.js 两头没对齐,而不是字体文件本身有问题。开发时看着正常,打包后失效,核心矛盾就出在构建流程对静态资源的处理逻辑上。
@font-face 声明位置和顺序错了
Tailwind 的 `@tailwind base` 会重置 `font-family` 继承链,如果 `@font-face` 写在它后面,浏览器可能注册失败或被 base 层覆盖。- 必须把
@font-face放在项目主 CSS 入口(如src/styles.css)的最顶部,严格位于@tailwind base之前 - 不能塞进组件级 CSS、
@layer components或 JS 中的字符串模板里 - 若使用 PostCSS 插件(如
postcss-import),确保导入顺序不打乱这个先后关系
font-family 字符串不完全一致
@font-face 里的font-family: "robotoMono" 和 tailwind.config.js 里 extend.fontFamily.robotoMono 是两条独立链路,匹配靠的是**字面量完全一致**:
- 大小写必须一致:
"RobotoMono"≠"robotoMono" - 引号类型要对应:CSS 中用双引号,配置中就得写
'"robotoMono"'(单引号包双引号) - 含空格或连字符的字体名必须加引号:
"Source Sans Pro"→ 配置中写'"Source Sans Pro"',不能漏引号或写成SourceSansPro - 如果字体名是
My-Font,类名就是font-My-Font,不是font-my-font(Tailwind 不自动转 kebab-case)
路径相对于 CSS 文件算错了
url() 是相对当前 CSS 文件解析的,不是 HTML 页面或 JS 路径:
- CSS 在
src/styles.css,字体在public/fonts/robotoMono.woff2→ 路径应为url("../public/fonts/robotoMono.woff2") - 直接粘贴该 URL 到浏览器地址栏测试是否 200;404 地址就是你要修正的目标
- 使用
file://协议打开 HTML 会因跨域禁止字体加载,必须走 http(s) 服务(如 Vite、Next.js dev server)
tailwind.config.js 用了 theme.fontFamily 而不是 extend
直接覆写fontFamily: { ... } 会清空 Tailwind 默认的 sans、serif、mono,导致 font-sans 等内置类彻底消失,且不会报错:
- ✅ 正确:
extend: { fontFamily: { robotoMono: ['"robotoMono"', 'ui-monospace', 'monospace'] } } - ❌ 错误:
fontFamily: { robotoMono: ['"robotoMono"', 'ui-monospace', 'monospace'] }
最后提醒一句:字体名拼错、路径少个点、引号漏一层、@font-face 放错位置——这些错误都不会触发构建报错,Tailwind 只是静默跳过,最终效果就是“字体加载了但没生效”,排查时得盯死这四点。


















