tailwind-v4-shadcn

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Tailwind v4 + shadcn/ui Production Stack

Tailwind v4 + shadcn/ui 生产环境搭建方案

Production-tested: WordPress Auditor (https://wordpress-auditor.webfonts.workers.dev) Last Updated: 2026-01-20 Versions: tailwindcss@4.1.18, @tailwindcss/vite@4.1.18 Status: Production Ready ✅

经生产环境验证:WordPress Auditor(https://wordpress-auditor.webfonts.workers.dev) 最后更新:2026-01-20 版本信息:tailwindcss@4.1.18, @tailwindcss/vite@4.1.18 状态:可用于生产环境 ✅

Quick Start (Follow This Exact Order)

快速开始(严格按照以下步骤执行)

bash
undefined
bash
undefined

1. Install dependencies

1. 安装依赖

pnpm add tailwindcss @tailwindcss/vite pnpm add -D @types/node tw-animate-css pnpm dlx shadcn@latest init
pnpm add tailwindcss @tailwindcss/vite pnpm add -D @types/node tw-animate-css pnpm dlx shadcn@latest init

2. Delete v3 config if exists

2. 如果存在v3配置文件则删除

rm tailwind.config.ts # v4 doesn't use this file

**vite.config.ts**:
```typescript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import path from 'path'

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: { alias: { '@': path.resolve(__dirname, './src') } }
})
components.json (CRITICAL):
json
{
  "tailwind": {
    "config": "",              // ← Empty for v4
    "css": "src/index.css",
    "baseColor": "slate",
    "cssVariables": true
  }
}

rm tailwind.config.ts # v4 不使用该文件

**vite.config.ts**:
```typescript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import path from 'path'

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: { alias: { '@': path.resolve(__dirname, './src') } }
})
components.json(至关重要):
json
{
  "tailwind": {
    "config": "",              // ← v4 此处留空
    "css": "src/index.css",
    "baseColor": "slate",
    "cssVariables": true
  }
}

The Four-Step Architecture (MANDATORY)

四步架构模式(必须严格执行)

Skipping steps will break your theme. Follow exactly:
跳过任何步骤都会导致主题失效,请严格遵循:

Step 1: Define CSS Variables at Root

步骤1:在根节点定义CSS变量

css
/* src/index.css */
@import "tailwindcss";
@import "tw-animate-css";  /* Required for shadcn/ui animations */

:root {
  --background: hsl(0 0% 100%);      /* ← hsl() wrapper required */
  --foreground: hsl(222.2 84% 4.9%);
  --primary: hsl(221.2 83.2% 53.3%);
  /* ... all light mode colors */
}

.dark {
  --background: hsl(222.2 84% 4.9%);
  --foreground: hsl(210 40% 98%);
  --primary: hsl(217.2 91.2% 59.8%);
  /* ... all dark mode colors */
}
Critical: Define at root level (NOT inside
@layer base
). Use
hsl()
wrapper.
css
/* src/index.css */
@import "tailwindcss";
@import "tw-animate-css";  /* shadcn/ui 动画必需 */

:root {
  --background: hsl(0 0% 100%);      /* ← 必须使用hsl()包裹 */
  --foreground: hsl(222.2 84% 4.9%);
  --primary: hsl(221.2 83.2% 53.3%);
  /* ... 所有浅色模式颜色 */
}

.dark {
  --background: hsl(222.2 84% 4.9%);
  --foreground: hsl(210 40% 98%);
  --primary: hsl(217.2 91.2% 59.8%);
  /* ... 所有深色模式颜色 */
}
关键注意事项:在根级别定义(不要放在
@layer base
内部),使用
hsl()
包裹颜色值。

Step 2: Map Variables to Tailwind Utilities

步骤2:将变量映射到Tailwind工具类

css
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
  /* ... map ALL CSS variables */
}
Why: Generates utility classes (
bg-background
,
text-primary
). Without this, utilities won't exist.
css
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
  /* ... 映射所有CSS变量 */
}
作用:生成工具类(如
bg-background
text-primary
)。缺少此步骤,工具类将无法生效。

Step 3: Apply Base Styles

步骤3:应用基础样式

css
@layer base {
  body {
    background-color: var(--background);  /* NO hsl() wrapper here */
    color: var(--foreground);
  }
}
Critical: Reference variables directly. Never double-wrap:
hsl(var(--background))
.
css
@layer base {
  body {
    background-color: var(--background);  /* 此处不要使用hsl()包裹 */
    color: var(--foreground);
  }
}
关键注意事项:直接引用变量,切勿双重包裹:
hsl(var(--background))

Step 4: Result - Automatic Dark Mode

步骤4:实现效果 - 自动深色模式

tsx
<div className="bg-background text-foreground">
  {/* No dark: variants needed - theme switches automatically */}
</div>

tsx
<div className="bg-background text-foreground">
  {/* 无需使用dark:前缀 - 主题会自动切换 */}
</div>

Dark Mode Setup

深色模式设置

1. Create ThemeProvider (see
templates/theme-provider.tsx
)
2. Wrap App:
typescript
// src/main.tsx
import { ThemeProvider } from '@/components/theme-provider'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
    <App />
  </ThemeProvider>
)
3. Add Theme Toggle:
bash
pnpm dlx shadcn@latest add dropdown-menu
See
reference/dark-mode.md
for ModeToggle component.

1. 创建ThemeProvider(参考
templates/theme-provider.tsx
2. 包裹应用:
typescript
// src/main.tsx
import { ThemeProvider } from '@/components/theme-provider'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
    <App />
  </ThemeProvider>
)
3. 添加主题切换按钮:
bash
pnpm dlx shadcn@latest add dropdown-menu
参考
reference/dark-mode.md
获取ModeToggle组件代码。

Critical Rules

关键规则

✅ Always Do:

✅ 必须执行:

  1. Wrap colors with
    hsl()
    in
    :root
    /
    .dark
    :
    --bg: hsl(0 0% 100%);
  2. Use
    @theme inline
    to map all CSS variables
  3. Set
    "tailwind.config": ""
    in components.json
  4. Delete
    tailwind.config.ts
    if exists
  5. Use
    @tailwindcss/vite
    plugin (NOT PostCSS)
  1. :root
    /
    .dark
    中使用
    hsl()
    包裹颜色:
    --bg: hsl(0 0% 100%);
  2. 使用
    @theme inline
    映射所有CSS变量
  3. 在components.json中设置
    "tailwind.config": ""
  4. 如果存在
    tailwind.config.ts
    则删除
  5. 使用
    @tailwindcss/vite
    插件(不要使用PostCSS)

❌ Never Do:

❌ 禁止操作:

  1. Put
    :root
    /
    .dark
    inside
    @layer base
    (causes cascade issues)
  2. Use
    .dark { @theme { } }
    pattern (v4 doesn't support nested @theme)
  3. Double-wrap colors:
    hsl(var(--background))
  4. Use
    tailwind.config.ts
    for theme (v4 ignores it)
  5. Use
    @apply
    directive (deprecated in v4, see error #7)
  6. Use
    dark:
    variants for semantic colors (auto-handled)
  7. Use
    @apply
    with
    @layer base
    or
    @layer components
    classes (v4 breaking change - use
    @utility
    instead) | Source
  8. Wrap ANY styles in
    @layer base
    without understanding CSS layer ordering (see error #8) | Source

  1. :root
    /
    .dark
    放在
    @layer base
    内部(会导致样式层级问题)
  2. 使用
    .dark { @theme { } }
    模式(v4不支持嵌套的@theme)
  3. 双重包裹颜色:
    hsl(var(--background))
  4. 使用
    tailwind.config.ts
    配置主题(v4会忽略该文件)
  5. 使用
    @apply
    指令(v4中已废弃,参考错误#7)
  6. 为语义化颜色使用
    dark:
    前缀(已自动处理)
  7. @layer base
    @layer components
    类中使用
    @apply
    (v4破坏性变更 - 使用
    @utility
    替代) | 来源
  8. 在不了解CSS层级顺序的情况下,将任何样式包裹在
    @layer base
    中(参考错误#8) | 来源

Common Errors & Solutions

常见错误与解决方案

This skill prevents 8 documented errors.
本方案可避免8种已记录的错误

1. ❌ tw-animate-css Import Error

1. ❌ tw-animate-css 导入错误

Error: "Cannot find module 'tailwindcss-animate'"
Cause: shadcn/ui deprecated
tailwindcss-animate
for v4.
Solution:
bash
undefined
错误信息:"Cannot find module 'tailwindcss-animate'"
原因:shadcn/ui在v4版本中废弃了
tailwindcss-animate
解决方案:
bash
undefined

✅ DO

✅ 正确做法

pnpm add -D tw-animate-css
pnpm add -D tw-animate-css

Add to src/index.css:

在src/index.css中添加:

@import "tailwindcss"; @import "tw-animate-css";
@import "tailwindcss"; @import "tw-animate-css";

❌ DON'T

❌ 错误做法

npm install tailwindcss-animate # v3 only

---
npm install tailwindcss-animate # 仅适用于v3

---

2. ❌ Colors Not Working

2. ❌ 颜色不生效

Error:
bg-primary
doesn't apply styles
Cause: Missing
@theme inline
mapping
Solution:
css
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
  /* ... map ALL CSS variables */
}

错误信息
bg-primary
样式未应用
原因:缺少
@theme inline
映射
解决方案:
css
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
  /* ... 映射所有CSS变量 */
}

3. ❌ Dark Mode Not Switching

3. ❌ 深色模式无法切换

Error: Theme stays light/dark
Cause: Missing ThemeProvider
Solution:
  1. Create ThemeProvider (see
    templates/theme-provider.tsx
    )
  2. Wrap app in
    main.tsx
  3. Verify
    .dark
    class toggles on
    <html>
    element

错误信息:主题始终保持浅色/深色
原因:缺少ThemeProvider
解决方案:
  1. 创建ThemeProvider(参考
    templates/theme-provider.tsx
  2. 在main.tsx中包裹应用
  3. 验证
    <html>
    元素上的
    .dark
    类是否正确切换

4. ❌ Duplicate @layer base

4. ❌ 重复的@layer base

Error: "Duplicate @layer base" in console
Cause: shadcn init adds
@layer base
- don't add another
Solution:
css
/* ✅ Correct - single @layer base */
@import "tailwindcss";

:root { --background: hsl(0 0% 100%); }

@theme inline { --color-background: var(--background); }

@layer base { body { background-color: var(--background); } }

错误信息:控制台出现"Duplicate @layer base"
原因:shadcn初始化时已添加
@layer base
- 请勿重复添加
解决方案:
css
/* ✅ 正确写法 - 单个@layer base */
@import "tailwindcss";

:root { --background: hsl(0 0% 100%); }

@theme inline { --color-background: var(--background); }

@layer base { body { background-color: var(--background); } }

5. ❌ Build Fails with tailwind.config.ts

5. ❌ 存在tailwind.config.ts导致构建失败

Error: "Unexpected config file"
Cause: v4 doesn't use
tailwind.config.ts
(v3 legacy)
Solution:
bash
rm tailwind.config.ts
v4 configuration happens in
src/index.css
using
@theme
directive.

错误信息:"Unexpected config file"
原因:v4不使用
tailwind.config.ts
(v3遗留文件)
解决方案:
bash
rm tailwind.config.ts
v4的配置通过
src/index.css
中的
@theme
指令完成。

6. ❌ @theme inline Breaks Dark Mode in Multi-Theme Setups

6. ❌ @theme inline 在多主题设置中破坏深色模式

Error: Dark mode doesn't switch when using
@theme inline
with custom variants (e.g.,
data-mode="dark"
) Source: GitHub Discussion #18560
Cause:
@theme inline
bakes variable VALUES into utilities at build time. When dark mode changes the underlying CSS variables, utilities don't update because they reference hardcoded values, not variables.
Why It Happens:
  • @theme inline
    inlines VALUES at build time:
    bg-primary
    background-color: oklch(...)
  • Dark mode overrides change the CSS variables, but utilities already have baked-in values
  • The CSS specificity chain breaks
Solution: Use
@theme
(without inline) for multi-theme scenarios:
css
/* ✅ CORRECT - Use @theme without inline */
@custom-variant dark (&:where([data-mode=dark], [data-mode=dark] *));

@theme {
  --color-text-primary: var(--color-slate-900);
  --color-bg-primary: var(--color-white);
}

@layer theme {
  [data-mode="dark"] {
    --color-text-primary: var(--color-white);
    --color-bg-primary: var(--color-slate-900);
  }
}
When to use inline:
  • Single theme + dark mode toggle (like shadcn/ui default) ✅
  • Referencing other CSS variables that don't change ✅
When NOT to use inline:
  • Multi-theme systems (data-theme="blue" | "green" | etc.) ❌
  • Dynamic theme switching beyond light/dark ❌
Maintainer Guidance (Adam Wathan):
"It's more idiomatic in v4 for the actual generated CSS to reference your theme variables. I would personally only use inline when things don't work without it."

错误信息:使用
@theme inline
和自定义变体(如
data-mode="dark"
)时,深色模式无法切换 来源GitHub讨论 #18560
原因
@theme inline
在构建时将变量值硬编码到工具类中。当深色模式修改底层CSS变量时,工具类不会更新,因为它们引用的是硬编码值而非变量。
具体原因:
  • @theme inline
    在构建时内联值:
    bg-primary
    background-color: oklch(...)
  • 深色模式覆盖修改CSS变量,但工具类已包含硬编码值
  • CSS优先级链断裂
解决方案:在多主题场景下使用不带inline的
@theme
:
css
/* ✅ 正确写法 - 使用不带inline的@theme */
@custom-variant dark (&:where([data-mode=dark], [data-mode=dark] *));

@theme {
  --color-text-primary: var(--color-slate-900);
  --color-bg-primary: var(--color-white);
}

@layer theme {
  [data-mode="dark"] {
    --color-text-primary: var(--color-white);
    --color-bg-primary: var(--color-slate-900);
  }
}
何时使用inline:
  • 单主题+深色模式切换(如shadcn/ui默认设置) ✅
  • 引用不变化的其他CSS变量 ✅
何时不使用inline:
  • 多主题系统(如data-theme="blue" | "green"等) ❌
  • 除浅色/深色外的动态主题切换 ❌
维护者指导(Adam Wathan):
"在v4中,更符合规范的做法是让生成的CSS引用主题变量。我个人只在不使用inline就无法工作的情况下才会使用它。"

7. ❌ @apply with @layer base/components (v4 Breaking Change)

7. ❌ 在@layer base/components中使用@apply(v4破坏性变更)

Error:
Cannot apply unknown utility class: custom-button
Source: GitHub Discussion #17082
Cause: In v3, classes defined in
@layer base
and
@layer components
could be used with
@apply
. In v4, this is a breaking architectural change.
Why It Happens: v4 doesn't "hijack" the native CSS
@layer
at-rule anymore. Only classes defined with
@utility
are available to
@apply
.
Migration:
css
/* ❌ v3 pattern (worked) */
@layer components {
  .custom-button {
    @apply px-4 py-2 bg-blue-500;
  }
}

/* ✅ v4 pattern (required) */
@utility custom-button {
  @apply px-4 py-2 bg-blue-500;
}

/* OR use native CSS */
@layer base {
  .custom-button {
    padding: 1rem 0.5rem;
    background-color: theme(colors.blue.500);
  }
}
Note: This skill already discourages
@apply
usage. This error is primarily for users migrating from v3.

错误信息
Cannot apply unknown utility class: custom-button
来源GitHub讨论 #17082
原因:在v3中,
@layer base
@layer components
中定义的类可以与
@apply
一起使用。在v4中,这是一个破坏性的架构变更。
具体原因:v4不再劫持原生CSS的
@layer
规则。只有使用
@utility
定义的类才能用于
@apply
迁移方案:
css
/* ❌ v3写法(曾生效) */
@layer components {
  .custom-button {
    @apply px-4 py-2 bg-blue-500;
  }
}

/* ✅ v4写法(必需) */
@utility custom-button {
  @apply px-4 py-2 bg-blue-500;
}

/* 或使用原生CSS */
@layer base {
  .custom-button {
    padding: 1rem 0.5rem;
    background-color: theme(colors.blue.500);
  }
}
注意:本方案已不推荐使用
@apply
。此错误主要针对从v3迁移的用户。

8. ❌ @layer base Styles Not Applying

8. ❌ @layer base 样式未生效

Error: Styles defined in
@layer base
seem to be ignored Source: GitHub Discussion #16002 | Discussion #18123
Cause: v4 uses native CSS layers. Base styles CAN be overridden by utility layers due to CSS cascade if layers aren't explicitly ordered.
Why It Happens:
  • v3: Tailwind intercepted
    @layer base/components/utilities
    and processed them specially
  • v4: Uses native CSS layers - if you don't import layers in the right order, precedence breaks
  • Styles ARE being applied, but utilities override them
Solution Option 1: Define layers explicitly:
css
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/base.css" layer(base);
@import "tailwindcss/components.css" layer(components);
@import "tailwindcss/utilities.css" layer(utilities);

@layer base {
  body {
    background-color: var(--background);
  }
}
Solution Option 2 (Recommended): Don't use
@layer base
- define styles at root level:
css
@import "tailwindcss";

:root {
  --background: hsl(0 0% 100%);
}

body {
  background-color: var(--background); /* No @layer needed */
}
Applies to: ALL base styles, not just color variables. Avoid wrapping ANY styles in
@layer base
unless you understand CSS layer ordering.

错误信息
@layer base
中定义的样式似乎被忽略 来源GitHub讨论 #16002 | 讨论 #18123
原因:v4使用原生CSS层级。如果未显式指定层级顺序,基础样式可能会被工具类层级覆盖。
具体原因:
  • v3:Tailwind会拦截
    @layer base/components/utilities
    并进行特殊处理
  • v4:使用原生CSS层级 - 如果未按正确顺序导入层级,优先级会断裂
  • 样式实际已应用,但被工具类覆盖
解决方案选项1:显式定义层级:
css
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/base.css" layer(base);
@import "tailwindcss/components.css" layer(components);
@import "tailwindcss/utilities.css" layer(utilities);

@layer base {
  body {
    background-color: var(--background);
  }
}
解决方案选项2(推荐):不使用
@layer base
- 在根级别定义样式:
css
@import "tailwindcss";

:root {
  --background: hsl(0 0% 100%);
}

body {
  background-color: var(--background); /* 不需要@layer */
}
适用范围:所有基础样式,不仅限于颜色变量。除非了解CSS层级顺序,否则避免将任何样式包裹在
@layer base
中。

Quick Reference

快速参考

SymptomCauseFix
bg-primary
doesn't work
Missing
@theme inline
Add
@theme inline
block
Colors all black/whiteDouble
hsl()
wrapping
Use
var(--color)
not
hsl(var(--color))
Dark mode not switchingMissing ThemeProviderWrap app in
<ThemeProvider>
Build fails
tailwind.config.ts
exists
Delete file
Animation errorsUsing
tailwindcss-animate
Install
tw-animate-css

症状原因解决方法
bg-primary
不生效
缺少
@theme inline
添加
@theme inline
代码块
颜色全为黑/白双重
hsl()
包裹
使用
var(--color)
而非
hsl(var(--color))
深色模式无法切换缺少ThemeProvider使用
<ThemeProvider>
包裹应用
构建失败存在
tailwind.config.ts
删除该文件
动画错误使用了
tailwindcss-animate
安装
tw-animate-css

What's New in Tailwind v4

Tailwind v4 新特性

OKLCH Color Space (December 2024)

OKLCH颜色空间(2024年12月)

Tailwind v4.0 replaced the entire default color palette with OKLCH, a perceptually uniform color space. Source: Tailwind v4.0 Release | OKLCH Migration Guide
Why OKLCH:
  • Perceptual consistency: HSL's "50% lightness" is visually inconsistent across hues (yellow appears much brighter than blue at same lightness)
  • Better gradients: Smooth transitions without muddy middle colors
  • Wider gamut: Supports colors beyond sRGB on modern displays
  • More vibrant colors: Eye-catching, saturated colors previously limited by sRGB
Browser Support (January 2026):
  • Chrome 111+, Firefox 113+, Safari 15.4+, Edge 111+
  • Global coverage: 93.1%
Automatic Fallbacks: Tailwind generates sRGB fallbacks for older browsers:
css
.bg-blue-500 {
  background-color: #3b82f6; /* sRGB fallback */
  background-color: oklch(0.6 0.24 264); /* Modern browsers */
}
Custom Colors: When defining custom colors, OKLCH is now preferred:
css
@theme {
  /* Modern approach (preferred) */
  --color-brand: oklch(0.7 0.15 250);

  /* Legacy approach (still works) */
  --color-brand: hsl(240 80% 60%);
}
Migration: No breaking changes - Tailwind generates fallbacks automatically. For new projects, use OKLCH-aware tooling for custom colors.
Tailwind v4.0将整个默认颜色 palette 替换为OKLCH,一种感知均匀的颜色空间。 来源Tailwind v4.0 发布说明 | OKLCH迁移指南
为什么选择OKLCH:
  • 感知一致性:HSL的"50%亮度"在不同色相下视觉不一致(黄色在相同亮度下比蓝色看起来亮得多)
  • 更好的渐变效果:过渡平滑,不会出现浑浊的中间色
  • 更广的色域:在现代显示器上支持超出sRGB的颜色
  • 更鲜艳的颜色:之前受sRGB限制的醒目饱和色现在可用
浏览器支持(2026年1月):
  • Chrome 111+, Firefox 113+, Safari 15.4+, Edge 111+
  • 全球覆盖率:93.1%
自动降级:Tailwind会为旧浏览器生成sRGB降级方案:
css
.bg-blue-500 {
  background-color: #3b82f6; /* sRGB降级方案 */
  background-color: oklch(0.6 0.24 264); /* 现代浏览器 */
}
自定义颜色:定义自定义颜色时,现在推荐使用OKLCH:
css
@theme {
  /* 现代写法(推荐) */
  --color-brand: oklch(0.7 0.15 250);

  /* 遗留写法(仍可使用) */
  --color-brand: hsl(240 80% 60%);
}
迁移:无破坏性变更 - Tailwind会自动生成降级方案。对于新项目,使用支持OKLCH的工具定义自定义颜色。

Built-in Features (No Plugin Needed)

内置特性(无需插件)

Container Queries (built-in as of v4.0):
tsx
<div className="@container">
  <div className="@md:text-lg @lg:grid-cols-2">
    Content responds to container width, not viewport
  </div>
</div>
Line Clamp (built-in as of v3.3):
tsx
<p className="line-clamp-3">Truncate to 3 lines with ellipsis...</p>
<p className="line-clamp-[8]">Arbitrary values supported</p>
<p className="line-clamp-(--teaser-lines)">CSS variable support</p>
Removed Plugins:
  • @tailwindcss/container-queries
    - Built-in now
  • @tailwindcss/line-clamp
    - Built-in since v3.3

容器查询(v4.0起内置):
tsx
<div className="@container">
  <div className="@md:text-lg @lg:grid-cols-2">
    内容响应容器宽度,而非视口宽度
  </div>
</div>
行数截断(v3.3起内置):
tsx
<p className="line-clamp-3">截断为3行并显示省略号...</p>
<p className="line-clamp-[8]">支持任意值</p>
<p className="line-clamp-(--teaser-lines)">支持CSS变量</p>
已移除的插件:
  • @tailwindcss/container-queries
    - 现已内置
  • @tailwindcss/line-clamp
    - v3.3起已内置

Tailwind v4 Plugins

Tailwind v4 插件

Use
@plugin
directive (NOT
require()
or
@import
):
Typography (for Markdown/CMS content):
bash
pnpm add -D @tailwindcss/typography
css
@import "tailwindcss";
@plugin "@tailwindcss/typography";
html
<article class="prose dark:prose-invert">{{ content }}</article>
Forms (cross-browser form styling):
bash
pnpm add -D @tailwindcss/forms
css
@import "tailwindcss";
@plugin "@tailwindcss/forms";
Container Queries (built-in, no plugin needed):
tsx
<div className="@container">
  <div className="@md:text-lg">Responds to container width</div>
</div>
Common Plugin Errors:
css
/* ❌ WRONG - v3 syntax */
@import "@tailwindcss/typography";

/* ✅ CORRECT - v4 syntax */
@plugin "@tailwindcss/typography";

使用
@plugin
指令(不要使用
require()
@import
):
排版插件(用于Markdown/CMS内容):
bash
pnpm add -D @tailwindcss/typography
css
@import "tailwindcss";
@plugin "@tailwindcss/typography";
html
<article class="prose dark:prose-invert">{{ content }}</article>
表单插件(跨浏览器表单样式):
bash
pnpm add -D @tailwindcss/forms
css
@import "tailwindcss";
@plugin "@tailwindcss/forms";
容器查询(内置,无需插件):
tsx
<div className="@container">
  <div className="@md:text-lg">响应容器宽度</div>
</div>
常见插件错误:
css
/* ❌ 错误 - v3语法 */
@import "@tailwindcss/typography";

/* ✅ 正确 - v4语法 */
@plugin "@tailwindcss/typography";

Setup Checklist

搭建检查清单

  • @tailwindcss/vite
    installed (NOT postcss)
  • vite.config.ts
    uses
    tailwindcss()
    plugin
  • components.json
    has
    "config": ""
  • NO
    tailwind.config.ts
    exists
  • src/index.css
    follows 4-step pattern:
    • :root
      /
      .dark
      at root level (not in @layer)
    • Colors wrapped with
      hsl()
    • @theme inline
      maps all variables
    • @layer base
      uses unwrapped variables
  • ThemeProvider wraps app
  • Theme toggle works

  • 已安装
    @tailwindcss/vite
    (不要使用postcss)
  • vite.config.ts
    使用
    tailwindcss()
    插件
  • components.json
    "config": ""
  • 不存在
    tailwind.config.ts
  • src/index.css
    遵循四步模式:
    • :root
      /
      .dark
      在根级别(不在@layer内部)
    • 颜色使用
      hsl()
      包裹
    • @theme inline
      映射所有变量
    • @layer base
      使用未包裹的变量
  • ThemeProvider已包裹应用
  • 主题切换功能正常

File Templates

文件模板

Available in
templates/
directory:
  • index.css - Complete CSS with all color variables
  • components.json - shadcn/ui v4 config
  • vite.config.ts - Vite + Tailwind plugin
  • theme-provider.tsx - Dark mode provider
  • utils.ts -
    cn()
    utility

可在
templates/
目录中获取:
  • index.css - 包含所有颜色变量的完整CSS文件
  • components.json - shadcn/ui v4配置文件
  • vite.config.ts - Vite + Tailwind插件配置
  • theme-provider.tsx - 深色模式提供者
  • utils.ts -
    cn()
    工具函数

Migration from v3

从v3迁移

See
reference/migration-guide.md
for complete guide.
Key Changes:
  • Delete
    tailwind.config.ts
  • Move theme to CSS with
    @theme inline
  • Replace
    @tailwindcss/line-clamp
    (now built-in:
    line-clamp-*
    )
  • Replace
    tailwindcss-animate
    with
    tw-animate-css
  • Update plugins:
    require()
    @plugin
完整指南请参考
reference/migration-guide.md
主要变更:
  • 删除
    tailwind.config.ts
  • 使用
    @theme inline
    将主题迁移到CSS
  • 替换
    @tailwindcss/line-clamp
    (现已内置:
    line-clamp-*
  • tw-animate-css
    替换
    tailwindcss-animate
  • 更新插件:
    require()
    @plugin

Additional Migration Gotchas

其他迁移注意事项

Automated Migration Tool May Fail

自动迁移工具可能失效

Warning: The
@tailwindcss/upgrade
utility often fails to migrate configurations. Source: Community Reports | GitHub Discussion #16642
Common failures:
  • Typography plugin configurations
  • Complex theme extensions
  • Custom plugin setups
Recommendation: Don't rely on automated migration. Follow manual steps in the migration guide instead.
警告:
@tailwindcss/upgrade
工具通常无法成功迁移配置。 来源: 社区报告 | GitHub讨论 #16642
常见失效场景:
  • 排版插件配置
  • 复杂的主题扩展
  • 自定义插件设置
建议: 不要依赖自动迁移。请遵循迁移指南中的手动步骤。

Default Element Styles Removed

默认元素样式已移除

Tailwind v4 takes a more minimal approach to Preflight, removing default styles for headings, lists, and buttons. Source: GitHub Discussion #16517 | Medium: Migration Problems
Impact:
  • All headings (
    <h1>
    through
    <h6>
    ) render at same size
  • Lists lose default padding
  • Visual regressions in existing projects
Solutions:
Option 1: Use @tailwindcss/typography for content pages:
bash
pnpm add -D @tailwindcss/typography
css
@import "tailwindcss";
@plugin "@tailwindcss/typography";
tsx
<article className="prose dark:prose-invert">
  {/* All elements styled automatically */}
</article>
Option 2: Add custom base styles:
css
@layer base {
  h1 { @apply text-4xl font-bold mb-4; }
  h2 { @apply text-3xl font-bold mb-3; }
  h3 { @apply text-2xl font-bold mb-2; }
  ul { @apply list-disc pl-6 mb-4; }
  ol { @apply list-decimal pl-6 mb-4; }
}
Tailwind v4对Preflight采取了更极简的方式,移除了标题、列表和按钮的默认样式。 来源: GitHub讨论 #16517 | Medium: 迁移问题
影响:
  • 所有标题(
    <h1>
    <h6>
    )显示为相同大小
  • 列表失去默认内边距
  • 现有项目出现视觉回归
解决方案:
方案1: 对内容页面使用@tailwindcss/typography:
bash
pnpm add -D @tailwindcss/typography
css
@import "tailwindcss";
@plugin "@tailwindcss/typography";
tsx
<article className="prose dark:prose-invert">
  {/* 所有元素自动应用样式 */}
</article>
方案2: 添加自定义基础样式:
css
@layer base {
  h1 { @apply text-4xl font-bold mb-4; }
  h2 { @apply text-3xl font-bold mb-3; }
  h3 { @apply text-2xl font-bold mb-2; }
  ul { @apply list-disc pl-6 mb-4; }
  ol { @apply list-decimal pl-6 mb-4; }
}

PostCSS Setup Complexity

PostCSS设置复杂度

Recommendation: Use
@tailwindcss/vite
plugin for Vite projects instead of PostCSS. Source: Medium: Migration Problems | GitHub Discussion #15764
Why Vite Plugin is Better:
typescript
// ✅ Vite Plugin - One line, no PostCSS config
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [react(), tailwindcss()],
})

// ❌ PostCSS - Multiple steps, plugin compatibility issues
// 1. Install @tailwindcss/postcss
// 2. Configure postcss.config.js
// 3. Manage plugin order
// 4. Debug plugin conflicts
PostCSS Problems Reported:
  • Error: "It looks like you're trying to use tailwindcss directly as a PostCSS plugin"
  • Multiple PostCSS plugins required:
    postcss-import
    ,
    postcss-advanced-variables
    ,
    tailwindcss/nesting
  • v4 PostCSS plugin is separate package:
    @tailwindcss/postcss
Official Guidance: The Vite plugin is recommended for Vite projects. PostCSS is for legacy setups or non-Vite environments.
建议: 对于Vite项目,使用
@tailwindcss/vite
插件而非PostCSS。 来源: Medium: 迁移问题 | GitHub讨论 #15764
为什么Vite插件更好:
typescript
// ✅ Vite插件 - 一行代码,无需PostCSS配置
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [react(), tailwindcss()],
})

// ❌ PostCSS - 多步骤,插件兼容性问题
// 1. 安装@tailwindcss/postcss
// 2. 配置postcss.config.js
// 3. 管理插件顺序
// 4. 调试插件冲突
已报告的PostCSS问题:
  • 错误: "It looks like you're trying to use tailwindcss directly as a PostCSS plugin"
  • 需要多个PostCSS插件:
    postcss-import
    ,
    postcss-advanced-variables
    ,
    tailwindcss/nesting
  • v4的PostCSS插件是单独的包:
    @tailwindcss/postcss
官方指导: 对于Vite项目,推荐使用Vite插件。PostCSS适用于遗留设置或非Vite环境。

Visual Changes

视觉变化

Ring Width Default: Changed from 3px to 1px Source: Medium: Migration Guide
  • ring
    class is now thinner
  • Use
    ring-3
    to match v3 appearance
tsx
// v3: 3px ring
<button className="ring">Button</button>

// v4: 1px ring (thinner)
<button className="ring">Button</button>

// Match v3 appearance
<button className="ring-3">Button</button>

默认环宽度: 从3px改为1px 来源: Medium: 迁移指南
  • ring
    类现在更细
  • 使用
    ring-3
    匹配v3的外观
tsx
// v3: 3px环
<button className="ring">按钮</button>

// v4: 1px环(更细)
<button className="ring">按钮</button>

// 匹配v3外观
<button className="ring-3">按钮</button>

Reference Documentation

参考文档

  • architecture.md - Deep dive into 4-step pattern
  • dark-mode.md - Complete dark mode implementation
  • common-gotchas.md - Troubleshooting guide
  • migration-guide.md - v3 → v4 migration

  • architecture.md - 四步模式深度解析
  • dark-mode.md - 完整深色模式实现指南
  • common-gotchas.md - 故障排除指南
  • migration-guide.md - v3 → v4迁移指南

Official Documentation

官方文档


Last Updated: 2026-01-20 Skill Version: 3.0.0 Tailwind v4: 4.1.18 (Latest) Production: WordPress Auditor (https://wordpress-auditor.webfonts.workers.dev)
Changelog:
  • v3.0.0 (2026-01-20): Major research update - added 3 TIER 1 errors (#6-8), expanded migration guide with community findings (TIER 2), added OKLCH color space section, PostCSS complexity warnings, and migration tool limitations
  • v2.0.1 (2026-01-03): Production verification
  • v2.0.0: Initial release with 5 documented errors

最后更新: 2026-01-20 方案版本: 3.0.0 Tailwind v4: 4.1.18(最新版) 生产环境验证: WordPress Auditor(https://wordpress-auditor.webfonts.workers.dev)
更新日志:
  • v3.0.0 (2026-01-20): 重大研究更新 - 添加3个一级错误(#6-8),结合社区发现扩展迁移指南(二级内容),添加OKLCH颜色空间章节、PostCSS复杂度警告和迁移工具限制说明
  • v2.0.1 (2026-01-03): 生产环境验证
  • v2.0.0: 初始发布,包含5种已记录的错误