六维教程

Tailwind CSS 复用与自定义

为什么要做复用

直接把工具类写在 HTML 上很方便,但当一个按钮、一个卡片在多处出现时,重复写一长串类名既难维护又容易漏改。Tailwind v4 提供几种方式把样式收敛起来,本篇讲最常用的三种:@apply、@utility、@layer。

@apply 提取成普通类

@apply 让你把多个工具类「应用」到一个普通 CSS 选择器里,得到一个自定义的样式类。

@import "tailwindcss";

.btn {
  @apply px-4 py-2 rounded bg-blue-500 text-white;
}

.btn:hover {
  @apply bg-blue-600;
}

之后在 HTML 里只需要写 class="btn",就能拿到这一组样式。

<button class="btn">提交</button>
<button class="btn">取消</button>

适用场景与局限

@apply 适合把「已经存在于工具类里的组合」重命名成语义类,比如 .btn、.card、.tag。

它有几点限制:

  • 只能套用 Tailwind 已有的工具类,不能凭空创造新行为
  • 不支持写在媒体查询、变体里的条件逻辑,复杂响应式还是建议在 HTML 上写
  • 过度使用会让 CSS 和 HTML 脱节,失去原子化的直观优势

经验法则是:组件级、反复出现的组合才提取,零散的样式留在 HTML 上。

@utility 定义全新工具类

@apply 只能复用已有工具类,而 @utility 用来定义一套全新的、可被响应式和状态变体使用的工具类。

@import "tailwindcss";

@utility text-balance {
  text-wrap: balance;
}

定义后 text-balance 可以像原生工具类一样使用,并且支持变体:

<h1 class="text-balance md:text-2xl">一段需要平衡排版的标题</h1>

@apply 与 @utility 的区别

  • @apply 是把已有工具类组合进一个普通类,生成的 .btn 不能用 hover:、md: 等前缀直接修饰(除非在 CSS 里单独写)
  • @utility 定义的是真正的工具类,天生支持 hover:、md:、dark: 等所有变体
  • 想做「语义组件类」用 @apply;想做「可组合的新原子能力」用 @utility

@layer 控制层级

Tailwind 内部把样式分成了几个层:base、components、utilities。默认情况下,@utility 进 utilities 层,@apply 写的普通类需要你决定放在哪一层。

@layer components {
  .card {
    @apply rounded-lg border p-4 shadow;
  }
}

@layer utilities {
  .no-scrollbar {
    scrollbar-width: none;
  }
}

把组件类放进 components 层,能确保它优先级低于 utilities,这样在 HTML 上写工具类时仍能覆盖组件默认值。

组件化思路

结合上面三种手段,一个常见的工作流是:

  • 用 @apply + @layer components 沉淀项目组件类(按钮、卡片、标签)
  • 用 @utility 补充框架没有的原子能力
  • 用 @theme 统一管理颜色、字体等令牌,组件类里引用主题变量
@import "tailwindcss";

@theme {
  --color-brand: #4f46e5;
}

@layer components {
  .btn {
    @apply px-4 py-2 rounded bg-brand text-white;
  }
  .btn:hover {
    @apply bg-brand/80;
  }
}

这样既保留了主题集中管理,又让 HTML 保持简洁。

上一篇
Tailwind CSS 主题定制 @theme
下一篇
Tailwind CSS 进阶技巧