Tailwind CSS v4 × Nuxt4 深度集成
Tailwind CSS v4 是一次架构级重写——从 JavaScript 配置迁移到 CSS-first 配置,构建速度提升 10 倍,并且原生支持 CSS 变量作为 Design Token。在 Nuxt4 生态中,
@nuxtjs/tailwindcss模块和@nuxt/ui组件库都已全面拥抱 v4。本章从 v4 的架构变革讲起,深入 CSS-first 配置、Nuxt UI 主题定制、Design Token 体系,最终落地一套完整的设计系统。
1. Tailwind v4 的架构变革
1.1 从 JS 配置到 CSS 配置
Tailwind v3 的配置写在 tailwind.config.js(JavaScript)中。v4 彻底改变了这个模式——配置写在 CSS 文件中:
/* v3:tailwind.config.js */
/* module.exports = { theme: { colors: { primary: '#3b82f6' } } } */
/* v4:app.css */
@import "tailwindcss";
@theme {
--color-primary: #3b82f6;
--font-family-sans: 'Inter', sans-serif;
--breakpoint-sm: 640px;
}这个变化不是简单的语法迁移,而是架构哲学的转变:
- 零 JavaScript:配置不再需要 Node.js 解析,纯 CSS 引擎处理
- CSS 变量原生:
@theme中的值自动生成 CSS 变量(var(--color-primary)) - 构建速度:新引擎用 Rust(Oxide)编写,全量构建 < 100ms,增量构建 < 10ms
- 更小的输出:智能检测消除未使用的样式,产物更精简
1.2 Nuxt4 集成
npx nuxi module add @nuxtjs/tailwindcss// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/tailwindcss'],
tailwindcss: {
cssPath: '~/assets/css/tailwind.css',
},
})/* assets/css/tailwind.css */
@import "tailwindcss";
@theme {
--color-primary: #3b82f6;
--color-secondary: #6366f1;
}@nuxtjs/tailwindcss 模块自动处理:
- 自动扫描
components/、pages/、layouts/中的类名 - HMR 热更新(修改 CSS 主题即时生效)
- 与 Nuxt DevTools 集成
2. @theme:CSS-first 配置详解
2.1 颜色系统
@theme {
/* 品牌色 */
--color-primary: #3b82f6;
--color-primary-50: #eff6ff;
--color-primary-100: #dbeafe;
--color-primary-500: #3b82f6;
--color-primary-900: #1e3a5f;
/* 语义色 */
--color-success: #22c55e;
--color-warning: #f59e0b;
--color-error: #ef4444;
--color-info: #06b6d4;
/* 中性色 */
--color-gray-50: #f9fafb;
--color-gray-900: #111827;
}@theme 中定义的颜色会自动生成工具类:bg-primary、text-primary-500、border-error。同时生成 CSS 变量,可以在自定义 CSS 中通过 var(--color-primary) 引用。
2.2 排版系统
@theme {
--font-family-sans: 'Inter', 'Noto Sans SC', sans-serif;
--font-family-mono: 'JetBrains Mono', monospace;
--font-size-xs: 0.75rem;
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--font-size-xl: 1.25rem;
--font-size-2xl: 1.5rem;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.75;
}2.3 间距与圆角
@theme {
--spacing-0: 0;
--spacing-1: 0.25rem;
--spacing-2: 0.5rem;
--spacing-4: 1rem;
--spacing-8: 2rem;
--radius-sm: 0.25rem;
--radius-md: 0.375rem;
--radius-lg: 0.5rem;
--radius-xl: 0.75rem;
--radius-full: 9999px;
}2.4 动画
@theme {
--animate-fade-in: fade-in 0.3s ease-out;
--animate-slide-up: slide-up 0.3s ease-out;
}
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slide-up {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}使用:<div class="animate-fade-in">。
3. Nuxt UI 主题定制
3.1 Nuxt UI 与 Tailwind v4
Nuxt UI v3 基于 Tailwind v4 和 Radix Vue 构建,提供 50+ 高质量组件。它的主题系统完全基于 CSS 变量:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/ui'],
ui: {
theme: {
colors: ['primary', 'secondary', 'success', 'warning', 'error'],
},
},
})3.2 组件级主题覆盖
Nuxt UI 的每个组件都有默认的样式变体,可以在 app.config.ts 中全局覆盖:
// app.config.ts
export default defineAppConfig({
ui: {
button: {
defaultVariants: {
size: 'md',
color: 'primary',
},
slots: {
base: 'rounded-lg font-medium transition-colors',
},
},
input: {
slots: {
root: 'relative',
base: 'rounded-lg border-gray-300 focus:border-primary focus:ring-primary',
},
},
},
})app.config.ts 中的覆盖是全局生效的——所有 <UButton> 组件都会使用你定义的样式。单个组件实例仍然可以通过 ui prop 局部覆盖。
3.3 组件实例覆盖
<template>
<UButton
:ui="{
base: 'rounded-full px-8',
}"
>
特殊按钮
</UButton>
</template>优先级:组件 ui prop > app.config.ts 全局配置 > Nuxt UI 默认样式。
4. Design Token 体系
4.1 什么是 Design Token
Design Token 是设计系统中可复用的最小设计决策单元——颜色、字号、间距、圆角、阴影等。它是设计师和开发者之间的契约:
设计师在 Figma 中定义:Primary Color = #3b82f6
↓
导出为 Design Token(JSON / CSS 变量)
↓
开发者在代码中使用:bg-primary / var(--color-primary)
4.2 三层 Token 架构
成熟的设计系统通常有三层 Token:
| 层级 | 命名示例 | 含义 | 示例值 |
|---|---|---|---|
| Global | --blue-500 | 原始色板值 | #3b82f6 |
| Alias | --color-primary | 语义化引用 | var(--blue-500) |
| Component | --button-bg | 组件级 Token | var(--color-primary) |
/* 第一层:原始值 */
@theme {
--blue-50: #eff6ff;
--blue-500: #3b82f6;
--blue-900: #1e3a5f;
}
/* 第二层:语义化别名 */
:root {
--color-primary: var(--blue-500);
--color-bg: var(--white);
--color-text: var(--gray-900);
}
/* 第三层:组件级(暗黑模式自动切换) */
.dark {
--color-primary: var(--blue-400);
--color-bg: var(--gray-950);
--color-text: var(--gray-100);
}三层架构的好处:更换品牌色时只需修改 Alias 层(--color-primary),不需要改动组件代码。
4.3 与 Figma 同步
设计师在 Figma 中定义 Token,通过工具自动同步到代码:
| 工具 | 方式 | 特点 |
|---|---|---|
| Figma Tokens | Figma 插件 + GitHub 同步 | 最流行 |
| Style Dictionary | JSON → 多平台代码 | Amazon 开源 |
| Panda CSS | 内置 Token 系统 | 类型安全 |
工作流:设计师修改 Figma Token → 自动生成 PR 更新 CSS 变量 → 代码审核合并。
5. 实用模式
5.1 响应式设计
Tailwind v4 的断点定义:
@theme {
--breakpoint-sm: 640px;
--breakpoint-md: 768px;
--breakpoint-lg: 1024px;
--breakpoint-xl: 1280px;
--breakpoint-2xl: 1536px;
}<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<VideoCard v-for="video in videos" :key="video.id" :video="video" />
</div>5.2 容器查询
Tailwind v4 原生支持容器查询——根据父容器而非视口宽度调整样式:
<div class="@container">
<div class="@sm:flex @sm:items-center">
<!-- 当父容器 >= 640px 时变为 flex 布局 -->
</div>
</div>容器查询在组件化开发中比媒体查询更实用——同一个卡片组件在侧边栏(窄)和主内容区(宽)自动适配。
5.3 自定义工具类
@utility content-auto {
content-visibility: auto;
}
@utility scrollbar-hide {
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}使用:<div class="content-auto scrollbar-hide">。
5.4 避免常见陷阱
动态类名不生效:
<!-- ❌ 动态拼接类名,Tailwind 无法检测 -->
<div :class="`bg-${color}-500`">
<!-- ✅ 使用完整类名映射 -->
<div :class="colorMap[color]">
<script setup>
const colorMap = {
primary: 'bg-primary-500',
success: 'bg-success-500',
error: 'bg-error-500',
}
</script>Tailwind 的 JIT 引擎通过静态分析源代码来检测类名,动态拼接的字符串无法被检测到。
本章小结
- Tailwind v4 = CSS-first:
@theme替代tailwind.config.js,构建速度提升 10 倍,原生 CSS 变量 - Nuxt 集成:
@nuxtjs/tailwindcss自动扫描 + HMR,@nuxt/ui基于 v4 提供 50+ 组件 - 主题定制三层:
@theme定义 Token →app.config.ts全局覆盖 → 组件uiprop 局部覆盖 - Design Token 三层架构:Global(原始值)→ Alias(语义化)→ Component(组件级),便于品牌切换
- 实用模式:容器查询替代媒体查询、
@utility自定义工具类、避免动态类名拼接