Next.js 14 中 Tailwind CSS 正常工作的关键是 content 路径正确覆盖 app/ 目录、@tailwind 指令三行齐全且无间隔、PostCSS 插件顺序为 'tailwindcss' 字符串,三者缺一不可;须使用 v3.x 版本,避免误升 v4 导致构建失败。

Next.js 14 中 Tailwind CSS 要能正常工作,关键不是“装上就行”,而是 content 路径配对、@tailwind 指令写对、PostCSS 插件顺序不颠倒——三者错一个,开发时样式就消失,构建后 CSS 就为空。
确认 Tailwind 版本与 Next.js 14 的兼容性
Next.js 14(App Router)默认搭配的是 Tailwind CSS v3.x(如 tailwindcss@3.4.4),不是 v4。v4 需要额外安装 @tailwindcss/postcss 并改写 postcss.config.js,但目前官方脚手架和绝大多数生产项目仍稳定运行在 v3 上。强行升 v4 容易触发 Cannot find module 'tailwindcss/plugin' 或构建时报 Invalid PostCSS plugin。
验证方式:检查 package.json 中 tailwindcss 版本号是否为 ^3.0.0 范围;若看到 @tailwindcss/postcss,说明已切 v4,需同步调整配置。
- 用
npx create-next-app@latest创建项目时选了 Tailwind,它自动装的就是 v3 - 手动安装请明确指定:
npm install -D tailwindcss postcss autoprefixer,不要加@latest - v3 的
postcss.config.js必须写成'tailwindcss'(字符串),不是require('tailwindcss')或@tailwindcss/postcss
tailwind.config.js 的 content 字段必须覆盖 App Router 路径
Tailwind 的 JIT 编译器靠扫描 content 列出的文件路径来提取类名。Next.js 14 默认用 app/ 目录,但旧教程常写 ./pages/**/*.{js,ts,jsx,tsx},这会导致所有类名不被识别,最终 CSS 文件只有重置样式,没有工具类。
正确写法是把 app/ 下所有 JSX/TSX/MDX 文件都纳入:
module.exports = {
content: [
"./app/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./lib/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: { extend: {} },
plugins: [],
}
- 如果用了
src/app结构,路径要改成./src/app/**/*.{...} - MDX 文件(如博客内容)必须显式加入,否则
className="text-lg"在.mdx里不会被扫描 - 路径末尾的
**/*不能省,否则子目录下文件不被递归扫描
全局样式文件中 @tailwind 指令缺一不可
Next.js 14 App Router 的全局样式入口是 app/globals.css。这里必须按顺序写全三行指令,漏掉任意一行都会导致对应层级样式丢失:
@tailwind base; @tailwind components; @tailwind utilities;
-
@tailwind base提供preflight重置,去掉浏览器默认边距、字体等 -
@tailwind components是空占位,留给你在@layer components里写可复用组件类(比如.btn) -
@tailwind utilities是核心,所有flex、text-red-500等原子类都来自这里 - 指令之间不能有空行或注释隔开,否则 PostCSS 解析失败(尤其
@tailwind components后面跟注释会静默失效)
动态类名(如 className={`${isOpen ? 'block' : 'hidden'}`)需要额外配置
这种写法在开发时可能显示正常,但生产构建(next build)后样式丢失——因为 Tailwind 默认只匹配纯字符串字面量,无法静态分析模板字符串里的分支结果。
解决方法有两个,按优先级推荐:
- 改用
clsx或tailwind-merge:它们在运行时拼接类名,且tailwind-merge还能自动去重、覆盖冲突类(比如text-red-500 text-blue-500只留后者) - 在
tailwind.config.js的content里加一条正则路径:"./app/**/*.{js,ts,jsx,tsx,mdx}"已覆盖大部分,但若类名来自外部 JSON 或 CMS 数据,就得在content中显式列出这些数据文件路径,或启用safeList - 避免在
content扫描范围外拼接类名,比如从localStorage读取字符串再塞进className,这种永远无法被扫描到
最常被忽略的一点:即使你写了 safeList,也得确保它写在 tailwind.config.js 的顶层,而不是嵌套在 theme 或 plugins 里;而且 safeList 不支持通配符,text-* 这种写法无效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











