shadcn-tailwind

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Styling with Tailwind CSS

基于Tailwind CSS的样式开发

Build accessible UIs using Tailwind CSS v4 utility classes and shadcn/ui component patterns. Tailwind v4 uses CSS-first configuration only - never create or modify
tailwind.config.js
/
tailwind.config.ts
.
Supports Radix UI (default) or Base UI as primitive libraries.
使用Tailwind CSS v4工具类和shadcn/ui组件模式构建无障碍UI。Tailwind v4仅支持CSS优先配置 - 永远不要创建或修改
tailwind.config.js
/
tailwind.config.ts
默认支持Radix UI作为原语组件库,也可选择Base UI。

Critical Rules

核心规则

No
tailwind.config.js
- CSS-First Only

禁止使用
tailwind.config.js
- 仅支持CSS优先配置

Tailwind v4 configures everything in CSS. Migrate any JS/TS config:
  • theme.extend.colors
    @theme { --color-*: ... }
  • plugins
    @plugin "..."
    or
    @utility
  • content
    @source "..."
  • tailwindcss-animate
    @import "tw-animate-css"
  • @layer utilities
    @utility name { ... }
Tailwind v4所有配置都在CSS中完成,请迁移所有JS/TS配置:
  • theme.extend.colors
    @theme { --color-*: ... }
  • plugins
    @plugin "..."
    @utility
  • content
    @source "..."
  • tailwindcss-animate
    @import "tw-animate-css"
  • @layer utilities
    @utility name { ... }

Always Use Semantic Color Tokens

始终使用语义化颜色令牌

tsx
// CORRECT - respects themes and dark mode
<div className="bg-primary text-primary-foreground">

// WRONG - breaks theming
<div className="bg-blue-500 text-white">
Always pair
bg-*
with
text-*-foreground
. Extend with success/warning/info in theming.md.
tsx
// 正确 - 适配主题和暗色模式
<div className="bg-primary text-primary-foreground">

// 错误 - 破坏主题系统
<div className="bg-blue-500 text-white">
始终将
bg-*
text-*-foreground
配对使用。可在theming.md中扩展成功/警告/提示等状态颜色。

Never Build Class Names Dynamically

禁止动态拼接类名

tsx
// WRONG - breaks Tailwind scanner
<div className={`bg-${color}-500`}>

// CORRECT - complete strings via lookup
const colorMap = { red: "bg-red-500", blue: "bg-blue-500" } as const
<div className={colorMap[color]}>
tsx
// 错误 - 无法被Tailwind扫描器识别
<div className={`bg-${color}-500`}>

// 正确 - 通过映射表使用完整类名字符串
const colorMap = { red: "bg-red-500", blue: "bg-blue-500" } as const
<div className={colorMap[color]}>

cn() Merge Order

cn()合并顺序

Defaults first, consumer
className
last (tailwind-merge last-wins):
tsx
className={cn(buttonVariants({ variant, size }), className)}  // correct
className={cn(className, buttonVariants({ variant, size }))}  // wrong
默认样式在前,传入的
className
在后(tailwind-merge遵循后定义优先规则):
tsx
className={cn(buttonVariants({ variant, size }), className)}  // 正确
className={cn(className, buttonVariants({ variant, size }))}  // 错误

Animation Performance

动画性能优化

tsx
// WRONG - transition-all causes layout thrashing
<div className="transition-all duration-300">

// CORRECT - transition only what changes
<div className="transition-colors duration-200">

// CORRECT - respect reduced motion
<div className="motion-safe:animate-fade-in">
tsx
// 错误 - transition-all会导致布局抖动
<div className="transition-all duration-300">

// 正确 - 仅为变化的属性添加过渡
<div className="transition-colors duration-200">

// 正确 - 适配系统减少动画偏好设置
<div className="motion-safe:animate-fade-in">

@theme
vs
@theme inline

@theme
@theme inline
区别

  • @theme
    - static tokens, overridable by plugins
  • @theme inline
    - references CSS variables, follows dark mode changes
css
@theme { --color-brand: oklch(0.6 0.2 250); }          /* static */
@theme inline { --color-primary: var(--primary); }       /* dynamic */
See components.md for more pitfalls and theming.md for color system reference.
  • @theme
    - 静态令牌,可被插件覆盖
  • @theme inline
    - 引用CSS变量,跟随暗色模式变化自动更新
css
@theme { --color-brand: oklch(0.6 0.2 250); }          /* 静态 */
@theme inline { --color-primary: var(--primary); }       /* 动态 */
更多常见陷阱请参考components.md,颜色系统参考请查看theming.md

Core Patterns

核心模式

CSS Variables for Theming

基于CSS变量的主题系统

shadcn/ui uses semantic CSS variables mapped to Tailwind utilities:
css
/* globals.css - Light mode */
:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --border: oklch(0.922 0 0);
  --radius: 0.5rem;
}

/* Dark mode */
.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
}

/* Tailwind v4: Map variables */
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
}
Usage in components:
tsx
// Background colors omit the "-background" suffix
<div className="bg-primary text-primary-foreground">
<div className="bg-muted text-muted-foreground">
<div className="bg-destructive text-destructive-foreground">
shadcn/ui使用映射到Tailwind工具类的语义化CSS变量:
css
/* globals.css - 亮色模式 */
:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --border: oklch(0.922 0 0);
  --radius: 0.5rem;
}

/* 暗色模式 */
.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
}

/* Tailwind v4: 变量映射 */
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
}
组件中使用方式:
tsx
// 背景色省略"-background"后缀
<div className="bg-primary text-primary-foreground">
<div className="bg-muted text-muted-foreground">
<div className="bg-destructive text-destructive-foreground">

Component Authoring Pattern

组件开发模式

Components use plain functions with
data-slot
attributes (React 19 - no
forwardRef
):
tsx
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"

const buttonVariants = cva(
  "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
        destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
        outline: "border border-input bg-background hover:bg-accent",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline",
      },
      size: {
        default: "h-9 px-4 py-2",
        sm: "h-8 px-3 text-xs",
        lg: "h-10 px-8",
        icon: "size-9",
      },
    },
    defaultVariants: { variant: "default", size: "default" },
  }
)

// Plain function with React.ComponentProps (not forwardRef)
function Button({
  className,
  variant,
  size,
  ...props
}: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants>) {
  return (
    <button
      data-slot="button"
      className={cn(buttonVariants({ variant, size, className }))}
      {...props}
    />
  )
}

// Usage
<Button variant="outline" size="sm">Click me</Button>
Icon spacing with
data-icon
:
tsx
<Button>
  <Spinner data-icon="inline-start" />
  Generating...
</Button>

<Button>
  <CheckIcon data-slot="icon" />
  Save Changes
</Button>
组件使用普通函数搭配
data-slot
属性(React 19无需
forwardRef
):
tsx
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"

const buttonVariants = cva(
  "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
        destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
        outline: "border border-input bg-background hover:bg-accent",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline",
      },
      size: {
        default: "h-9 px-4 py-2",
        sm: "h-8 px-3 text-xs",
        lg: "h-10 px-8",
        icon: "size-9",
      },
    },
    defaultVariants: { variant: "default", size: "default" },
  }
)

// 使用React.ComponentProps的普通函数(无需forwardRef)
function Button({
  className,
  variant,
  size,
  ...props
}: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants>) {
  return (
    <button
      data-slot="button"
      className={cn(buttonVariants({ variant, size, className }))}
      {...props}
    />
  )
}

// 使用示例
<Button variant="outline" size="sm">点击我</Button>
data-icon
实现图标间距:
tsx
<Button>
  <Spinner data-icon="inline-start" />
  生成中...
</Button>

<Button>
  <CheckIcon data-slot="icon" />
  保存更改
</Button>

Responsive Design

响应式设计

Mobile-first breakpoints:
tsx
// Stack on mobile, grid on tablet+
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">

// Hide on mobile
<div className="hidden md:block">

// Different layouts per breakpoint
<div className="flex flex-col md:flex-row lg:gap-8">
  <aside className="w-full md:w-64">
  <main className="flex-1">
</div>

// Responsive text sizes
<h1 className="text-3xl md:text-4xl lg:text-5xl">
移动端优先断点:
tsx
// 移动端堆叠,平板及以上使用网格布局
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">

// 移动端隐藏
<div className="hidden md:block">

// 不同断点适配不同布局
<div className="flex flex-col md:flex-row lg:gap-8">
  <aside className="w-full md:w-64">
  <main className="flex-1">
</div>

// 响应式文字大小
<h1 className="text-3xl md:text-4xl lg:text-5xl">

Container Queries

容器查询

First-class in Tailwind v4, no plugin needed:
tsx
<div className="@container">
  <div className="grid gap-4 @sm:grid-cols-2 @lg:grid-cols-3">
    Responds to container width, not viewport
  </div>
</div>

// Named containers
<div className="@container/sidebar">
  <nav className="hidden @md/sidebar:block">
Tailwind v4原生支持,无需额外插件:
tsx
<div className="@container">
  <div className="grid gap-4 @sm:grid-cols-2 @lg:grid-cols-3">
    响应容器宽度而非视口宽度变化
  </div>
</div>

// 命名容器
<div className="@container/sidebar">
  <nav className="hidden @md/sidebar:block">

Dark Mode

暗色模式

tsx
// Use dark: prefix - but prefer semantic colors over manual dark: overrides
<div className="bg-background text-foreground">          // auto dark mode
<div className="bg-white dark:bg-black">                 // manual override

// Use next-themes for toggle: useTheme() → setTheme("dark" | "light")
// Always add suppressHydrationWarning to <html> to prevent flash
tsx
// 使用dark:前缀 - 但优先使用语义化颜色而非手动dark:覆盖
<div className="bg-background text-foreground">          // 自动适配暗色模式
<div className="bg-white dark:bg-black">                 // 手动覆盖

// 使用next-themes实现切换:useTheme() → setTheme("dark" | "light")
// 始终为<html>标签添加suppressHydrationWarning避免加载闪屏

Common Component Patterns

常用组件模式

Card

卡片

tsx
<div className="rounded-xl border bg-card text-card-foreground shadow">
  <div className="flex flex-col space-y-1.5 p-6">
    <h3 className="font-semibold leading-none tracking-tight">Title</h3>
    <p className="text-sm text-muted-foreground">Description</p>
  </div>
  <div className="p-6 pt-0">Content</div>
  <div className="flex items-center p-6 pt-0">Footer</div>
</div>
tsx
<div className="rounded-xl border bg-card text-card-foreground shadow">
  <div className="flex flex-col space-y-1.5 p-6">
    <h3 className="font-semibold leading-none tracking-tight">标题</h3>
    <p className="text-sm text-muted-foreground">描述</p>
  </div>
  <div className="p-6 pt-0">内容</div>
  <div className="flex items-center p-6 pt-0">底部</div>
</div>

Form Field

表单字段

tsx
<div className="space-y-2">
  <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
    Email
  </label>
  <input
    type="email"
    className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
  />
  <p className="text-sm text-muted-foreground">Helper text</p>
</div>
tsx
<div className="space-y-2">
  <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
    邮箱
  </label>
  <input
    type="email"
    className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
  />
  <p className="text-sm text-muted-foreground">提示文字</p>
</div>

Badge

徽章

tsx
const badgeVariants = cva(
  "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors",
  {
    variants: {
      variant: {
        default: "border-transparent bg-primary text-primary-foreground shadow",
        secondary: "border-transparent bg-secondary text-secondary-foreground",
        destructive: "border-transparent bg-destructive text-destructive-foreground",
        outline: "text-foreground",
      },
    },
  }
)
tsx
const badgeVariants = cva(
  "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors",
  {
    variants: {
      variant: {
        default: "border-transparent bg-primary text-primary-foreground shadow",
        secondary: "border-transparent bg-secondary text-secondary-foreground",
        destructive: "border-transparent bg-destructive text-destructive-foreground",
        outline: "text-foreground",
      },
    },
  }
)

Layout Patterns

布局模式

Centered Layout

居中布局

tsx
<div className="flex min-h-screen items-center justify-center">
  <div className="w-full max-w-md space-y-8 p-8">
    {/* Content */}
  </div>
</div>
tsx
<div className="flex min-h-screen items-center justify-center">
  <div className="w-full max-w-md space-y-8 p-8">
    {/* 内容 */}
  </div>
</div>

Sidebar Layout

侧边栏布局

tsx
<div className="flex h-screen">
  <aside className="w-64 border-r bg-muted/40">Sidebar</aside>
  <main className="flex-1 overflow-auto">Content</main>
</div>
tsx
<div className="flex h-screen">
  <aside className="w-64 border-r bg-muted/40">侧边栏</aside>
  <main className="flex-1 overflow-auto">内容</main>
</div>

Dashboard Grid

仪表盘网格

tsx
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
  <Card className="col-span-2">Wide card</Card>
  <Card>Regular</Card>
  <Card>Regular</Card>
  <Card className="col-span-4">Full width</Card>
</div>
tsx
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
  <Card className="col-span-2">宽卡片</Card>
  <Card>普通卡片</Card>
  <Card>普通卡片</Card>
  <Card className="col-span-4">全宽卡片</Card>
</div>

Accessibility Patterns

无障碍模式

Focus Visible

聚焦可见样式

tsx
<button className="focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
tsx
<button className="focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">

Screen Reader Only

仅屏幕阅读器可见

tsx
<span className="sr-only">Close dialog</span>
tsx
<span className="sr-only">关闭弹窗</span>

Disabled States

禁用状态

tsx
<button className="disabled:cursor-not-allowed disabled:opacity-50" disabled>
tsx
<button className="disabled:cursor-not-allowed disabled:opacity-50" disabled>

Tailwind v4 Features

Tailwind v4特性

CSS-First Configuration

CSS优先配置

css
@import "tailwindcss";

/* Custom utilities (replaces @layer utilities) */
@utility tab-highlight-none {
  -webkit-tap-highlight-color: transparent;
}

/* Custom variants */
@custom-variant pointer-fine (@media (pointer: fine));

/* Source control */
@source inline("{hover:,}bg-red-{50,100,200}");
@source not "./legacy";
css
@import "tailwindcss";

/* 自定义工具类(替代@layer utilities) */
@utility tab-highlight-none {
  -webkit-tap-highlight-color: transparent;
}

/* 自定义变体 */
@custom-variant pointer-fine (@media (pointer: fine));

/* 源文件控制 */
@source inline("{hover:,}bg-red-{50,100,200}");
@source not "./legacy";

@theme Directive

@theme指令

css
@theme {
  --color-primary: oklch(0.205 0 0);
  --font-sans: "Inter", system-ui;
}

/* With CSS variables (shadcn/ui pattern) */
@theme inline {
  --color-primary: var(--primary);
}
css
@theme {
  --color-primary: oklch(0.205 0 0);
  --font-sans: "Inter", system-ui;
}

/* 搭配CSS变量(shadcn/ui模式) */
@theme inline {
  --color-primary: var(--primary);
}

Animation

动画

css
@import "tw-animate-css";
tsx
<div className="animate-fade-in">
<div className="animate-slide-in-from-top">
css
@import "tw-animate-css";
tsx
<div className="animate-fade-in">
<div className="animate-slide-in-from-top">

v4.1 Features

v4.1特性

tsx
// Text shadows
<h1 className="text-shadow-sm text-4xl font-bold">

// Gradient masks for fade effects
<div className="mask-linear-to-b">Fades to transparent at bottom</div>

// Pointer-aware sizing
<button className="pointer-fine:py-1 pointer-coarse:py-3">

// Form validation after user interaction
<input className="user-valid:border-success user-invalid:border-destructive" />

// Overflow wrap for long strings
<p className="overflow-wrap-anywhere">verylongwordthatneedstowrap</p>
tsx
// 文字阴影
<h1 className="text-shadow-sm text-4xl font-bold">

// 渐变蒙版实现淡入淡出效果
<div className="mask-linear-to-b">底部渐变为透明</div>

// 指针类型感知尺寸
<button className="pointer-fine:py-1 pointer-coarse:py-3">

// 用户交互后触发表单验证
<input className="user-valid:border-success user-invalid:border-destructive" />

// 长字符串自动换行
<p className="overflow-wrap-anywhere">verylongwordthatneedstowrap</p>

v4.2 Features (February 2026)

v4.2特性(2026年2月发布)

tsx
// Logical block properties (RTL/writing-mode aware)
<div className="pbs-4 pbe-8 mbs-2">
<div className="border-bs-2 border-be">

// Logical sizing (replaces w-*/h-* for logical layouts)
<div className="inline-full block-screen">

// Font feature settings
<p className="font-features-['tnum','liga']">Tabular numbers</p>

// New color palettes: mauve, olive, mist, taupe
<div className="bg-mauve-100 text-olive-900">
Deprecation:
start-*
/
end-*
deprecated in favor of
inset-s-*
/
inset-e-*
.
tsx
// 逻辑块属性(适配RTL/书写模式)
<div className="pbs-4 pbe-8 mbs-2">
<div className="border-bs-2 border-be">

// 逻辑尺寸(替代w-*/h-*用于逻辑布局)
<div className="inline-full block-screen">

// 字体特性设置
<p className="font-features-['tnum','liga']">等宽数字</p>

// 新调色板:mauve、olive、mist、taupe
<div className="bg-mauve-100 text-olive-900">
废弃说明:
start-*
/
end-*
已废弃,推荐使用
inset-s-*
/
inset-e-*
替代。

OKLCH Colors

OKLCH颜色

All shadcn/ui colors use OKLCH format:
oklch(lightness chroma hue)
. Lightness 0-1, chroma 0-0.4 (0 = gray), hue 0-360. Base palettes: Neutral, Zinc, Slate, Stone, Gray. See theming.md for complete palettes and OKLCH reference.
所有shadcn/ui颜色使用OKLCH格式:
oklch(明度 彩度 色相)
。明度范围0-1,彩度范围0-0.4(0=灰色),色相范围0-360。基础调色板:Neutral、Zinc、Slate、Stone、Gray。完整调色板和OKLCH参考请查看theming.md

Best Practices

最佳实践

Prefer Semantic Colors

优先使用语义化颜色

tsx
// Good - uses theme
<div className="bg-background text-foreground">

// Avoid - hardcoded
<div className="bg-white text-black dark:bg-zinc-950">
tsx
// 推荐 - 使用主题配置
<div className="bg-background text-foreground">

// 避免 - 硬编码颜色
<div className="bg-white text-black dark:bg-zinc-950">

Group Related Utilities

相关工具类分组排列

tsx
<div className="
  flex items-center justify-between
  rounded-lg border
  bg-card text-card-foreground
  p-4 shadow-sm
  hover:bg-accent
">
tsx
<div className="
  flex items-center justify-between
  rounded-lg border
  bg-card text-card-foreground
  p-4 shadow-sm
  hover:bg-accent
">

Avoid Arbitrary Values

避免使用任意值

tsx
// Prefer design tokens
<div className="p-4 text-sm">

// Avoid when unnecessary
<div className="p-[17px] text-[13px]">
tsx
// 优先使用设计令牌
<div className="p-4 text-sm">

// 非必要情况下避免使用
<div className="p-[17px] text-[13px]">

Installation & CLI

安装与CLI

bash
undefined
bash
undefined

Create new project with visual style + primitive selection

创建新项目,支持选择视觉风格和原语组件库

npx shadcn create
npx shadcn create

Initialize in existing project

在现有项目中初始化

pnpm dlx shadcn@latest init
pnpm dlx shadcn@latest init

Add components

添加组件

pnpm dlx shadcn@latest add button card form
pnpm dlx shadcn@latest add button card form

Add from community registries

从社区注册表添加组件

npx shadcn add @acme/button @internal/auth-system
npx shadcn add @acme/button @internal/auth-system

View/search registries

查看/搜索注册表

npx shadcn view @acme/auth-system npx shadcn search @tweakcn -q "dark" npx shadcn list @acme
npx shadcn view @acme/auth-system npx shadcn search @tweakcn -q "dark" npx shadcn list @acme

Add MCP server for AI integration

添加MCP服务器用于AI集成

npx shadcn@latest mcp init
npx shadcn@latest mcp init

Update existing components

更新现有组件

pnpm dlx shadcn@latest add button --overwrite
undefined
pnpm dlx shadcn@latest add button --overwrite
undefined

Visual Styles

视觉风格

npx shadcn create
offers 5 built-in visual styles:
  • Vega - Classic shadcn/ui look
  • Nova - Compact, reduced padding
  • Maia - Soft and rounded, generous spacing
  • Lyra - Boxy and sharp, pairs with mono fonts
  • Mira - Dense, for data-heavy interfaces
These rewrite component code (not just CSS variables) to match the selected style.
npx shadcn create
提供5种内置视觉风格:
  • Vega - 经典shadcn/ui外观
  • Nova - 紧凑风格,减少内边距
  • Maia - 柔和圆角,宽松间距
  • Lyra - 方正锐利,适合搭配等宽字体
  • Mira - 高密度设计,适合数据密集型界面
这些风格会重写组件代码(不只是CSS变量)以匹配选择的视觉效果。

Troubleshooting

故障排查

Colors not updating: Check CSS variable in globals.css → verify
@theme inline
includes the mapping → clear build cache.
Dark mode flash on load: Add
suppressHydrationWarning
to
<html>
tag and ensure ThemeProvider wraps app with
attribute="class"
.
Found
tailwind.config.js
:
Delete it. Run
npx @tailwindcss/upgrade
to auto-migrate to CSS-first config. All customization belongs in your CSS file via
@theme
,
@utility
,
@plugin
.
Classes not detected: Check
@source
directives cover your component paths. Never construct class names dynamically (see Critical Rules).
颜色不更新: 检查globals.css中的CSS变量 → 确认
@theme inline
包含对应映射 → 清除构建缓存。
加载时暗色模式闪屏:
<html>
标签添加
suppressHydrationWarning
,确保ThemeProvider包裹整个应用并配置
attribute="class"
检测到
tailwind.config.js
删除该文件,运行
npx @tailwindcss/upgrade
自动迁移到CSS优先配置,所有自定义配置都应通过
@theme
@utility
@plugin
写在CSS文件中。
类名未被识别: 检查
@source
指令是否覆盖了所有组件路径,永远不要动态拼接类名(参考核心规则)。

Component Patterns

组件模式

For detailed component patterns see components.md:
  • Composition: asChild pattern, data-slot attributes
  • Typography: Heading scales, prose styles, inline code
  • Forms: React Hook Form + Zod, Field component with FieldSet/FieldGroup
  • Icons: Lucide icons with data-icon attributes
  • Inputs: OTP, file, grouped inputs
  • Dialogs: Modal patterns and composition
  • Data Tables: TanStack table integration
  • Toasts: Sonner notifications
  • Pitfalls: cn() order, form defaultValues, dialog nesting, sticky, server/client
详细组件模式请参考components.md
  • 组合: asChild模式、data-slot属性
  • 排版: 标题层级、prose样式、行内代码
  • 表单: React Hook Form + Zod、带FieldSet/FieldGroup的Field组件
  • 图标: 带data-icon属性的Lucide图标
  • 输入框: OTP、文件上传、分组输入框
  • 弹窗: 模态框模式与组合
  • 数据表格: TanStack table集成
  • 提示: Sonner通知
  • 常见陷阱: cn()顺序、表单defaultValues、弹窗嵌套、sticky、服务端/客户端组件

Resources

资源

See theming.md for complete color system reference:
  • @theme
    vs
    @theme inline
    (critical for dark mode)
  • Status color extensions (success, warning, info)
  • Z-index scale and animation tokens
  • All base palettes (Neutral, Zinc, Slate, Stone, Gray)
完整颜色系统参考请查看theming.md
  • @theme
    @theme inline
    区别(暗色模式适配核心)
  • 状态颜色扩展(成功、警告、提示)
  • Z-index层级和动画令牌
  • 所有基础调色板(Neutral、Zinc、Slate、Stone、Gray)

Summary

总结

Key concepts:
  • v4 CSS-first only - no
    tailwind.config.js
    , all config in CSS
  • Semantic colors only - never use raw palette (
    bg-blue-500
    ), always
    bg-primary
  • Always pair
    bg-*
    with
    text-*-foreground
  • Never build class names dynamically - use object lookup with complete strings
  • cn() order - defaults first, consumer
    className
    last
  • No
    transition-all
    - transition only specific properties
  • @theme inline
    for dynamic theming,
    @theme
    for static tokens
  • Author components as plain functions with
    data-slot
    (React 19)
  • Apply CVA for component variants
  • Use
    motion-safe:
    /
    motion-reduce:
    for animations
  • Choose Radix UI or Base UI as primitive library
This skill targets Tailwind CSS v4.2 with shadcn/ui. For component-specific examples, see components.md. For color system, see theming.md.
核心概念:
  • 仅支持v4 CSS优先配置 - 无
    tailwind.config.js
    ,所有配置写在CSS中
  • 仅使用语义化颜色 - 永远不要使用原始调色板颜色(如
    bg-blue-500
    ),始终使用
    bg-primary
    这类语义化类
  • 始终配对使用
    bg-*
    text-*-foreground
  • 禁止动态拼接类名 - 使用对象映射表提供完整类名字符串
  • cn()顺序 - 默认样式在前,传入的
    className
    在后
  • 不要使用
    transition-all
    - 仅为具体变化的属性添加过渡
  • @theme inline
    用于动态主题,
    @theme
    用于静态令牌
  • 使用普通函数搭配
    data-slot
    开发组件(React 19)
  • 使用CVA实现组件变体
  • 为动画添加
    motion-safe:
    /
    motion-reduce:
    适配系统偏好
  • 选择Radix UI或Base UI作为原语组件库
本教程针对搭配shadcn/ui使用的Tailwind CSS v4.2编写,组件具体示例请查看components.md,颜色系统参考请查看theming.md