mcpField
T
tailwind-css

tailwind-css

github.com/dralgorhythm设计与 UI12962 次安装14 周前更新
代码仓库

关于 tailwind-css

面向 Web UI 开发者的 Tailwind CSS 4.x 技能,介绍实用类样式、主题配置与响应式组件工作流。其重点是 v4 的 CSS 优先配置和自动内容检测。

主要功能

  1. 01CSS 优先主题配置
  2. 02自动检测内容
  3. 03响应式实用类样式
  4. 04组件与状态样式模式
  5. 05从 v3 迁移到 v4

适用场景

  1. 01为 Vite 项目配置 Tailwind CSS 4.x
  2. 02用实用类构建响应式组件
  3. 03使用 @theme 定义设计令牌
  4. 04将 Tailwind CSS v3 项目迁移至 v4

MCP 相关

文档提及使用 Context7 MCP 查询 Tailwind CSS 完整实用类参考。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dralgorhythm/claude-agentic-framework --skill tailwind-css

安装后在 Claude Code 中输入/tailwind-css确认已加载。

详细介绍

Tailwind CSS 4.x

平台: Web(Tailwind CSS 4.x)。如需移动端样式,请参阅 nativewind 技能(适用于 React Native 的 Tailwind 3.x)。

概览

实用工具优先的 CSS 框架,可用于快速开发 UI。Tailwind CSS 4.x 引入了 CSS 优先的配置方式、自动内容检测,以及采用新引擎带来的性能提升。

安装: pnpm add -D tailwindcss @tailwindcss/vite

API 参考: 使用 Context7 MCP 获取完整的实用工具类参考(mcp__context7__resolve-library-id → tailwindcss)。

v4 的主要变化

  • CSS 优先配置 - 在 CSS 中使用 @theme,而非 tailwind.config.js
  • 单次导入 - 使用 @import "tailwindcss",而非单独的指令
  • 自动内容检测 - 无需 content 数组
  • 全新颜色系统 - 支持广色域的 OKLCH 颜色
  • 内置 Vite 插件 - 使用 @tailwindcss/vite 实现最佳集成

工作流

设置 Tailwind v4:

  1. 安装依赖:pnpm add -D tailwindcss @tailwindcss/vite
  2. 在 vite.config.ts 中添加 Vite 插件
  3. 创建包含 @import "tailwindcss" 的 index.css
  4. 使用 @theme 指令自定义主题
  5. 测试构建流程并确认样式已加载

创建组件:

  1. 从语义化 HTML 结构开始
  2. 应用布局实用工具类(flex、grid)
  3. 添加间距实用工具类(p-、m-、gap-*)
  4. 使用颜色、排版和边框设置样式
  5. 添加响应式变体(sm:、md:、lg:)
  6. 在多个视口中测试

自定义主题:

  1. 使用 CSS 中的 @theme 定义设计令牌
  2. 添加自定义颜色、间距和字体
  3. 创建语义化颜色别名
  4. 确认令牌在各组件中均可使用

配置

Vite 配置
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  plugins: [react(), tailwindcss()],
});
CSS 入口点
/* src/index.css */
@import "tailwindcss";

@theme {
  /* Brand colors (OKLCH for wide gamut) */
  --color-primary: oklch(0.6 0.2 250);
  --color-secondary: oklch(0.6 0.15 300);
  --color-success: oklch(0.7 0.2 150);
  --color-warning: oklch(0.8 0.15 85);
  --color-danger: oklch(0.6 0.25 25);

  /* Typography */
  --font-sans: "Inter", system-ui, sans-serif;
  --font-mono: "Fira Code", monospace;

  /* Custom spacing */
  --spacing-128: 32rem;

  /* Custom animations */
  --animate-fade-in: fade-in 0.3s ease-out;
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Dark mode variant */
@variant dark (&:where(.dark, .dark *));

响应式设计

默认断点(移动端优先):sm: 640px | md: 768px | lg: 1024px | xl: 1280px | 2xl: 1536px

// Stack on mobile, grid on desktop
<div className="flex flex-col md:flex-row gap-4">
  <div className="w-full md:w-1/2">Left</div>
  <div className="w-full md:w-1/2">Right</div>
</div>

// Responsive grid
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
  {items.map(item => <div key={item.id} className="rounded-lg border p-4">{item.content}</div>)}
</div>

// Responsive typography
<h1 className="text-2xl sm:text-3xl md:text-4xl lg:text-5xl">Scales with viewport</h1>

// Show/hide at breakpoints
<div className="hidden lg:block">Desktop only</div>
<div className="block lg:hidden">Mobile only</div>

自定义断点:在 @theme 中添加 --breakpoint-demo: 1440px;。

暗色模式

function App() {
  const [isDark, setIsDark] = useState(false);
  useEffect(() => { document.documentElement.classList.toggle('dark', isDark); }, [isDark]);
  return (
    <div className="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
      <button onClick={() => setIsDark(!isDark)}>Toggle Dark Mode</button>
    </div>
  );
}

组件模式

按钮
// Primary
<button className="rounded-md bg-blue-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors">
  Primary
</button>

// Secondary
<button className="rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors">
  Secondary
</button>
卡片
// Basic card
<div className="rounded-lg border border-gray-200 bg-white p-6 shadow-sm">
  <h3 className="text-lg font-semibold text-gray-900">Card Title</h3>
  <p className="mt-2 text-sm text-gray-600">Description</p>
</div>

// Card with header/footer
<div className="rounded-lg border border-gray-200 bg-white overflow-hidden">
  <div className="border-b border-gray-200 bg-gray-50 px-6 py-4">
    <h3 className="text-lg font-semibold text-gray-900">Header</h3>
  </div>
  <div className="p-6"><p className="text-sm text-gray-600">Content</p></div>
  <div className="border-t border-gray-200 bg-gray-50 px-6 py-4">
    <button className="text-sm font-medium text-blue-600 hover:text-blue-700">Action</button>
  </div>
</div>
表单输入框
<div className="space-y-1">
  <label htmlFor="email" className="block text-sm font-medium text-gray-700">Email</label>
  <input
    type="email"
    id="email"
    className="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm placeholder-gray-400 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
    placeholder="[email protected]"
  />
</div>

高级模式

变体修饰符
// Group hover — child reacts to parent hover
<div className="group hover:bg-gray-100">
  <h3 className="group-hover:text-blue-600">Changes on parent hover</h3>
</div>

// Peer — sibling state
<input type="checkbox" className="peer" />
<label className="peer-checked:text-blue-600">Changes when checked</label>

// Data attributes
<div data-state="active" className="data-[state=active]:bg-blue-100">Active state</div>

// Structural: first:, last:, odd:, even:
<li className="first:rounded-t-lg last:rounded-b-lg border-b last:border-b-0">Item</li>
任意值和自定义实用工具类
// Arbitrary values with []
<div className="top-[117px] bg-[#1da1f2] grid-cols-[1fr_500px_2fr]">Custom values</div>
<div className="w-[calc(100%-2rem)] bg-[var(--brand-color)]">CSS var + calc</div>
/* Custom utilities with @utility */
@utility scrollbar-hide {
  -ms-overflow-style: none;
  scrollbar-width: none;
  &::-webkit-scrollbar { display: none; }
}

从 v3 迁移

v3 模式v4 模式
tailwind.config.jsCSS 中的 @theme
@tailwind base; 等@import "tailwindcss"
content: [...]自动检测
PostCSS 插件@tailwindcss/vite 插件

步骤: 安装新软件包 → 将 PostCSS 配置替换为 Vite 插件 → 替换 @tailwind 指令 → 将主题移至 @theme → 移除 content 数组 → 测试。

最佳实践

  • 采用移动端优先的方法 - 从基础样式开始,再添加响应式变体
  • 使用语义化颜色名称 - 通过 @theme 定义 primary、secondary、danger
  • 保持类名有序 - 布局 → 间距 → 颜色 → 排版 → 状态
  • 谨慎使用任意值 - 优先使用主题令牌
  • 使用 group- 和 peer- 实用工具类**处理 hover/focus 状态
  • 使用 Vite 插件 - @tailwindcss/vite 可提供最佳性能

反模式

  • 使用 tailwind.config.js 进行自定义(应使用 @theme)
  • 使用 @tailwind 指令(应使用 @import "tailwindcss")
  • 手动配置 content 数组(v4 会自动检测)
  • 在 Vite 中使用 PostCSS 插件(应使用 @tailwindcss/vite)
  • 采用桌面端优先的响应式设计(不适合移动端)
  • 硬编码颜色,而不使用主题令牌
  • 忽视无障碍功能(缺少焦点状态)

反馈循环

# Check generated CSS size (target < 50KB)
pnpm build

# Watch for changes
pnpm dev

通过按 Tab 键遍历交互元素来测试焦点状态。确认 focus:ring-* 实用工具类清晰可见。在浏览器开发者工具中检查颜色对比度。

评论

支持 Markdown