@apply与样式复用
本教程共 50 篇 · 第 42 篇 · 更新于 2026-07-29 · 约 6 分钟阅读
42. @apply 与样式复用
本节目标:掌握
@apply指令的用法,学会将多个工具类组合成自定义类,理解在组件框架中正确使用@apply的方式。
@apply 能让你在 CSS 里直接”复用”已有的工具类。当你不得不写自定义 CSS 时,它是保持设计令牌一致的桥梁。
基本用法
@import "tailwindcss";
/* 将多个工具类组合成一个自定义类 */
.btn {
@apply px-4 py-2 bg-blue-500 text-white rounded-lg font-medium;
}
.btn-danger {
@apply px-4 py-2 bg-red-500 text-white rounded-lg font-medium;
}
.card {
@apply p-6 bg-white rounded-xl shadow-md;
}
<button class="btn">主要按钮</button>
<button class="btn-danger">危险按钮</button>
<div class="card">卡片内容</div>
与变体结合
@apply 可以和 Tailwind 的变体一起使用:
.btn {
@apply px-4 py-2 bg-blue-500 text-white rounded-lg font-medium;
}
/* 在 HTML 中使用变体 */
<button class="btn hover:bg-blue-600 focus:ring-2 focus:ring-blue-300">
带交互状态的按钮
</button>
也可以在 @apply 中使用响应式前缀:
.heading {
@apply text-2xl font-bold;
}
/* 在 HTML 中使用响应式 */
<h1 class="heading md:text-3xl lg:text-4xl">响应式标题</h1>
覆盖工具类
在 components 层定义的类可以被工具类覆盖:
@layer components {
.btn {
@apply px-4 py-2 bg-blue-500 text-white rounded-lg;
}
}
<!-- rounded-none 会覆盖 .btn 中的 rounded-lg -->
<button class="btn rounded-none">无圆角按钮</button>
这是因为 Tailwind 的分层系统:components 层的优先级低于 utilities 层,所以工具类可以覆盖组件类。
在 Vue/Svelte 中使用
v4 中,组件的 <style> 块无法直接访问主 CSS 中定义的变量和工具类。需要使用 @reference 导入:
Vue 组件
<template>
<h1>Hello world!</h1>
</template>
<style>
/* 导入主样式以获取主题变量和工具类 */
@reference "../../app.css";
h1 {
@apply text-2xl font-bold text-red-500;
}
</style>
如果只使用默认主题(没有自定义 @theme),可以直接导入 tailwindcss:
<style>
@reference "tailwindcss";
h1 {
@apply text-2xl font-bold text-red-500;
}
</style>
Svelte 组件
<h1>Hello world!</h1>
<style>
@reference "../app.css";
h1 {
@apply text-2xl font-bold text-red-500;
}
</style>
替代方案:直接使用 CSS 变量
如果不想用 @apply,可以直接使用 CSS 变量:
<style>
h1 {
font-size: var(--text-2xl);
font-weight: var(--font-weight-bold);
color: var(--color-red-500);
}
</style>
这种方式不需要 @reference,性能也更好(Tailwind 不需要处理这些样式)。
何时使用 @apply
@apply 不是万能的。Tailwind 官方建议:优先考虑工具类,只在必要时使用 @apply。
适合使用 @apply 的场景
- 覆盖第三方库样式:需要写自定义 CSS 来覆盖组件库样式时
- 全局基础样式:为 HTML 元素设置默认样式
- 复杂组件样式:样式太多,写在 class 里影响可读性
/* 覆盖第三方日期选择器样式 */
.flatpickr-calendar {
@apply shadow-xl rounded-xl border-gray-200;
}
.flatpickr-day.selected {
@apply bg-blue-500 border-blue-500 text-white;
}
不适合使用 @apply 的场景
- 简单样式:直接在 HTML 写工具类更清晰
- 一次性样式:不会复写的样式没必要抽成类
- 响应式样式:工具类的响应式前缀更灵活
<!-- 推荐:直接用工具类 -->
<button class="px-4 py-2 bg-blue-500 text-white rounded-lg">
按钮
</button>
<!-- 不推荐:为了这个简单样式用 @apply -->
<!-- .btn { @apply px-4 py-2 bg-blue-500 text-white rounded-lg; } -->
与 v3 的区别
v3 中 @apply 可以在任何地方使用,包括 @layer 里:
/* v3 写法 */
@layer components {
.btn {
@apply px-4 py-2 bg-blue-500 text-white rounded-lg;
}
}
v4 中 @layer 不再用于定义工具类,而是使用 @utility:
/* v4 写法 */
@utility btn {
@apply px-4 py-2 bg-blue-500 text-white rounded-lg;
}
Notev4 的
@utility注册的类会自动支持变体(hover、focus 等),而@layer components中的类在 v4 中不再自动支持变体。
常见问题
@apply 不生效
检查是否正确导入了 Tailwind:
@import "tailwindcss"; /* 必须在文件顶部 */
在 Vue/Svelte 组件中,检查是否使用了 @reference。
@apply 与重要修饰符
v4 中 ! 放在类名末尾:
.btn {
@apply px-4 py-2 bg-blue-500! text-white!;
}
@apply 与暗色模式
.card {
@apply bg-white text-gray-900;
}
/* 在 HTML 中使用暗色变体 */
<div class="card dark:bg-gray-800 dark:text-white">
支持暗色模式的卡片
</div>
@apply 是工具类和传统 CSS 之间的桥梁。用得好能省不少事,但别滥用——大多数情况下,直接在 HTML 里写工具类更简单直接。