返回博客
技术 2025年2月9日 4 分钟阅读 · 760 字

Tailwind CSS 4 设计系统实践:从工具类到组件化封装

Tailwind CSS 4 的 CSS-first 配置、oklch 色彩空间与 @layer 指令如何构建可维护的设计系统。

#Tailwind CSS #CSS #设计系统 #前端工程
本文由 AI 辅助生成,经人工审核发布

CSS-First 配置

Tailwind 4 摒弃了 tailwind.config.js,改为 CSS 原生配置:

@import "tailwindcss";

@theme {
  --color-primary: oklch(0.70 0.15 165);
  --color-primary-light: oklch(0.80 0.10 165);
  --color-surface: oklch(0.20 0.02 250);
  --color-deep-text: oklch(0.95 0.01 250);
  --radius-card: 1rem;
  --shadow-glass: 0 8px 32px oklch(0 0 0 / 0.12);
}

@theme 中定义的变量会自动生成对应的工具类:--color-primary 生成 bg-primarytext-primaryborder-primary 等。

oklch 色彩空间

Tailwind 4 默认使用 oklch 而非 hex/rgboklch 的三个维度:

  • L(Lightness):0=黑,1=白
  • C(Chroma):饱和度,0=灰
  • H(Hue):色相,0-360 度
/* oklch 的优势:感知均匀 */
--color-primary: oklch(0.70 0.15 165);    /* 绿色 */
--color-primary-hover: oklch(0.65 0.15 165); /* 仅降低亮度,色相不变 */

在传统 HSL 中,降低 Lightness 会导致色相偏移。oklch 的感知均匀性保证了亮度变化时色彩一致性。

动态色相系统

利用 CSS 变量驱动 oklch 的 H 维度,实现全站动态换色:

@theme {
  --color-primary: oklch(0.70 0.15 var(--hue, 165));
  --color-primary-light: oklch(0.80 0.10 var(--hue, 165));
}

/* JavaScript 修改 --hue 即可全站换色 */
document.documentElement.style.setProperty('--hue', '350');

@layer 与优先级

Tailwind 4 的层叠顺序:

1. @layer theme      → @theme 定义的变量
2. @layer base       → reset 和基础样式
3. @layer components → 自定义组件类
4. @layer utilities  → 工具类(pt-4, flex 等)

常见陷阱

@import "tailwindcss" 之后写无 @layer 包裹的 CSS,优先级会高于所有 Tailwind 工具类:

@import "tailwindcss";

/* ❌ 危险:这会覆盖所有 Tailwind 的 padding 工具类 */
* { padding: 0; margin: 0; }

/* ✅ 正确:放入 base 层 */
@layer base {
  * { box-sizing: border-box; }
}

组件化封装

玻璃卡片

@layer components {
  .glass-card {
    background: color-mix(in srgb, var(--color-surface) 70%, transparent);
    backdrop-filter: blur(12px);
    border: 1px solid oklch(1 0 0 / 0.08);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-glass);
    transition: all 0.3s ease;
  }
  
  .glass-card:hover {
    border-color: var(--color-primary);
    transform: translateY(-2px);
  }
}

color-mix(in srgb, ...) 是 CSS 原生函数,比 rgba() 更灵活——可以混合任意两个颜色。

透明度修饰符

Tailwind 4 中任何颜色都可以用 / 语法控制透明度:

<div class="bg-primary/10 border-primary/20 text-primary/80">

但使用 CSS 变量时需要用 color-mix

/* 不能直接写 var(--color-primary) / 10% */
/* 需要用 color-mix */
background: color-mix(in srgb, var(--color-primary) 10%, transparent);

响应式设计

Tailwind 4 默认使用 min-width 移动优先断点:

<!-- 默认(移动端):单列 -->
<!-- md(768px+):两列 -->
<!-- lg(1024px+):三列 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">

容器查询

Tailwind 4 内置容器查询支持:

<div class="@container">
  <div class="grid grid-cols-1 @md:grid-cols-2 @lg:grid-cols-3">
    <!-- 根据父容器宽度而非视口宽度响应 -->
  </div>
</div>

@md@lg 是容器查询断点,让组件可以在不同容器尺寸下自适应,不依赖视口大小。

动画与过渡

@layer utilities {
  @keyframes float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-8px); }
  }
  
  .animate-float {
    animation: float 3s ease-in-out infinite;
  }
  
  .card-stagger {
    opacity: 0;
    animation: fadeInUp 0.5s ease forwards;
  }
  
  @keyframes fadeInUp {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
  }
}

通过 animation-delay 实现错峰动画:

<div class="card-stagger" style="animation-delay: 0ms">Card 1</div>
<div class="card-stagger" style="animation-delay: 60ms">Card 2</div>
<div class="card-stagger" style="animation-delay: 120ms">Card 3</div>

总结

Tailwind CSS 4 的设计理念是「CSS-first」——配置回到 CSS 文件,利用 CSS 原生特性(变量、color-mixoklch、容器查询)而非 JavaScript 工具链。这减少了构建步骤,提高了开发体验,同时保持了工具类的灵活性和组件化的可维护性。