@apply 必须在 Tailwind 的 PostCSS 编译流程中生效,仅支持已注册的原子类,需配合 @layer components 且置于 @tailwind 指令之后;不支持响应式前缀、伪类变体、动态值及自定义类。

@apply 不是“写完就能用”的语法糖,它必须在 Tailwind 的 PostCSS 编译流程里才能生效,且只接受已注册的原子类。直接往任意 .css 文件里贴 @apply,99% 会静默失效。
为什么 @apply 在你的 CSS 文件里没效果
根本原因是:浏览器和原生构建流程根本不认识 @apply —— 它只是 Tailwind 的 PostCSS 插件做的文本替换。文件没被 PostCSS 处理,@apply 就会被忽略,不报错、不渲染、不警告。
- 你新建了个
src/components/Button.css,在里面写@apply py-2 px-4 bg-blue-600→ 不生效(Vite/webpack 默认只处理入口 CSS,比如src/index.css) - 你在
public/style.css里写@apply→ 不生效(public/下的文件通常绕过构建流程) - 你用了
style.scss并在里面写@apply→ 极大概率失效(Sass 编译器先跑,PostCSS 插件还没机会处理@apply) - 你在 Vue 单文件组件的
<style scoped>里写@apply,但没加@reference "tailwindcss";→ 静默失败(v3.3+ 强制要求作用域引用)
@apply 必须配合 @layer components 使用
不是随便套个 @layer 就行——必须是 @layer components { },且只能放在 Tailwind 的主入口 CSS 文件里(通常是 src/index.css 或 src/styles.css)。
- 错误写法:
@layer utilities { .btn { @apply ... } }→ 可能触发样式覆盖或 JIT 漏生成 - 错误写法:
@layer base { .btn { @apply ... } }→ 基础层不参与工具类排序,hover/focus 等变体可能失效 - 正确结构:
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.btn-primary {
@apply py-2 px-4 rounded bg-blue-600 text-white font-medium hover:bg-blue-700 transition-colors;
}
}
注意:@layer components 必须出现在所有 @tailwind 指令之后,否则 Tailwind 不识别。
立即学习“前端免费学习笔记(深入)”;
@apply 能用哪些类?不能用哪些?
@apply 只展开 Tailwind 已注册的原子类,不是所有合法 CSS 值都能塞进去。
- ✅ 支持:
@apply text-blue-500 font-bold p-4(纯工具类,无响应式前缀、无伪类、无变量) - ❌ 不支持:
@apply md:px-6(响应式前缀需在 JSX 中直接写) - ❌ 不支持:
@apply hover:bg-blue-700 focus:ring-2(伪类变体不能在@apply中声明,必须保留在 HTML class 属性里) - ❌ 不支持:
@apply bg-[#3b82f6](动态值、任意值语法不被解析) - ❌ 不支持:
@apply my-custom-class(不能嵌套自定义类,my-custom-class不是 Tailwind 原生工具类)
常见翻车点:@apply p-4 rounded-lg my-shadow 中的 my-shadow 是你自己定义的,PurgeCSS 扫描不到,上线后直接被删。
什么时候真该用 @apply?别为了“看着短”硬上
多数人用 @apply 是为压缩 JSX 里的长 class 字符串,但这容易掩盖语义、增加调试成本。真正值得提取的,必须同时满足:
- 同一组类名(字面量完全一致)已在项目中真实复用 ≥ 3 次(不是“我觉得以后会用”)
- 代表稳定 UI 单元,比如
form-input、card-sm,而不是mt-4 pl-6 flex-wrap这种临时组合 - 不含任何响应式前缀、状态修饰符、动态值
- 你确认这个组合短期内不会重构(改一处
@apply,所有地方都要回归验证) - 已在
tailwind.config.js的content字段里覆盖到该 CSS 文件路径,确保类名被扫描注册
最常被忽略的一点:JSX 里仍要手动加响应式类。比如你定义了 .btn-primary,但在 md:flex 场景下想让它变成行内元素,就得写 class="btn-primary md:flex" —— btn-primary 本身不带 md:,靠 @apply 搞不定。


















