tailwind-theme-builder

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Tailwind Theme Builder

Tailwind 主题构建工具

Set up a fully themed Tailwind v4 + shadcn/ui project with dark mode. Produces configured CSS, theme provider, and working component library.
搭建一个带有暗黑模式的、完整主题化的Tailwind v4 + shadcn/ui项目。生成已配置的CSS、主题提供器和可用的组件库。

Workflow

操作流程

Step 1: Install Dependencies

步骤1:安装依赖项

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

Delete v3 config if it exists

Delete v3 config if it exists

rm -f tailwind.config.ts
undefined
rm -f tailwind.config.ts
undefined

Step 2: Configure Vite

步骤2:配置Vite

Copy
assets/vite.config.ts
or add the Tailwind plugin:
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') } }
})
复制
assets/vite.config.ts
或添加Tailwind插件:
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') } }
})

Step 3: Four-Step CSS Architecture (Mandatory)

步骤3:四步式CSS架构(必填)

This exact order is required. Skipping steps breaks the theme.
src/index.css:
css
@import "tailwindcss";
@import "tw-animate-css";

/* 1. Define CSS variables at root (NOT inside @layer base) */
:root {
  --background: hsl(0 0% 100%);
  --foreground: hsl(222.2 84% 4.9%);
  --primary: hsl(221.2 83.2% 53.3%);
  --primary-foreground: hsl(210 40% 98%);
  /* ... all semantic tokens */
}

.dark {
  --background: hsl(222.2 84% 4.9%);
  --foreground: hsl(210 40% 98%);
  --primary: hsl(217.2 91.2% 59.8%);
  --primary-foreground: hsl(222.2 47.4% 11.2%);
}

/* 2. Map variables to Tailwind utilities */
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
}

/* 3. Apply base styles (NO hsl() wrapper here) */
@layer base {
  body {
    background-color: var(--background);
    color: var(--foreground);
  }
}
Result:
bg-background
,
text-primary
etc. work automatically. Dark mode switches via
.dark
class — no
dark:
variants needed for semantic colours.
必须严格遵循此顺序,跳过步骤会导致主题失效。
src/index.css:
css
@import "tailwindcss";
@import "tw-animate-css";

/* 1. Define CSS variables at root (NOT inside @layer base) */
:root {
  --background: hsl(0 0% 100%);
  --foreground: hsl(222.2 84% 4.9%);
  --primary: hsl(221.2 83.2% 53.3%);
  --primary-foreground: hsl(210 40% 98%);
  /* ... all semantic tokens */
}

.dark {
  --background: hsl(222.2 84% 4.9%);
  --foreground: hsl(210 40% 98%);
  --primary: hsl(217.2 91.2% 59.8%);
  --primary-foreground: hsl(222.2 47.4% 11.2%);
}

/* 2. Map variables to Tailwind utilities */
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
}

/* 3. Apply base styles (NO hsl() wrapper here) */
@layer base {
  body {
    background-color: var(--background);
    color: var(--foreground);
  }
}
效果:
bg-background
text-primary
等工具类可自动生效。暗黑模式通过
.dark
类切换——语义化颜色无需使用
dark:
变体。

Step 4: Set Up Dark Mode

步骤4:设置暗黑模式

Copy
assets/theme-provider.tsx
to your components directory, then wrap your app:
typescript
import { ThemeProvider } from '@/components/theme-provider'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
    <App />
  </ThemeProvider>
)
Add a theme toggle:
bash
pnpm dlx shadcn@latest add dropdown-menu
See
references/dark-mode.md
for the ModeToggle component.
assets/theme-provider.tsx
复制到你的组件目录,然后包裹应用:
typescript
import { ThemeProvider } from '@/components/theme-provider'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
    <App />
  </ThemeProvider>
)
添加主题切换器:
bash
pnpm dlx shadcn@latest add dropdown-menu
查看
references/dark-mode.md
获取ModeToggle组件的实现。

Step 5: Configure components.json

步骤5:配置components.json

json
{
  "tailwind": {
    "config": "",
    "css": "src/index.css",
    "baseColor": "slate",
    "cssVariables": true
  }
}
"config": ""
is critical — v4 doesn't use tailwind.config.ts.

json
{
  "tailwind": {
    "config": "",
    "css": "src/index.css",
    "baseColor": "slate",
    "cssVariables": true
  }
}
"config": ""
至关重要——v4不使用tailwind.config.ts。

Critical Rules

关键规则

Always:
  • Wrap colours with
    hsl()
    in
    :root
    /
    .dark
  • Use
    @theme inline
    to map all CSS variables
  • Use
    @tailwindcss/vite
    plugin (NOT PostCSS)
  • Delete
    tailwind.config.ts
    if it exists
Never:
  • Put
    :root
    /
    .dark
    inside
    @layer base
  • Use
    .dark { @theme { } }
    (v4 doesn't support nested @theme)
  • Double-wrap:
    hsl(var(--background))
  • Use
    @apply
    with
    @layer base
    classes (use
    @utility
    instead)

必须遵守:
  • :root
    /
    .dark
    中使用
    hsl()
    包裹颜色值
  • 使用
    @theme inline
    映射所有CSS变量
  • 使用
    @tailwindcss/vite
    插件(而非PostCSS)
  • 如果存在
    tailwind.config.ts
    则删除该文件
绝对禁止:
  • :root
    /
    .dark
    放入
    @layer base
    内部
  • 使用
    .dark { @theme { } }
    (v4不支持嵌套@theme)
  • 双重包裹:
    hsl(var(--background))
  • @layer base
    类中使用
    @apply
    (改用
    @utility

Common Errors

常见错误

SymptomCauseFix
bg-primary
doesn't work
Missing
@theme inline
Add
@theme inline
block
Colours all black/whiteDouble
hsl()
wrapping
Use
var(--colour)
not
hsl(var(--colour))
Dark mode not switchingMissing ThemeProviderWrap app in
<ThemeProvider>
Build fails
tailwind.config.ts
exists
Delete the file
Animation errorsUsing
tailwindcss-animate
Install
tw-animate-css
instead
@apply
fails on custom class
v4 breaking changeUse
@utility
instead of
@layer components
See
references/common-gotchas.md
for detailed error explanations with sources.

症状原因修复方案
bg-primary
不生效
缺少
@theme inline
添加
@theme inline
代码块
颜色全为黑/白双重
hsl()
包裹
使用
var(--colour)
而非
hsl(var(--colour))
暗黑模式无法切换缺少ThemeProvider
<ThemeProvider>
包裹应用
构建失败存在
tailwind.config.ts
删除该文件
动画报错使用了
tailwindcss-animate
改用
tw-animate-css
自定义类中
@apply
失效
v4的破坏性更新
@utility
替代
@layer components
查看
references/common-gotchas.md
获取带GitHub来源的详细错误说明。

Asset Files

资源文件

Copy from
assets/
directory:
  • index.css
    — Complete CSS with all colour variables
  • components.json
    — shadcn/ui v4 config
  • vite.config.ts
    — Vite + Tailwind plugin
  • theme-provider.tsx
    — Dark mode provider
  • utils.ts
    cn()
    utility
assets/
目录复制以下文件:
  • index.css
    — 包含所有颜色变量的完整CSS文件
  • components.json
    — shadcn/ui v4配置文件
  • vite.config.ts
    — Vite + Tailwind插件配置
  • theme-provider.tsx
    — 暗黑模式提供器
  • utils.ts
    cn()
    工具函数

Reference Files

参考文件

  • references/common-gotchas.md
    — 8 documented errors with GitHub sources
  • references/dark-mode.md
    — Complete dark mode implementation
  • references/architecture.md
    — Deep dive into 4-step pattern
  • references/migration-guide.md
    — v3 to v4 migration
  • references/common-gotchas.md
    — 8个带GitHub来源的已记录错误
  • references/dark-mode.md
    — 完整的暗黑模式实现方案
  • references/architecture.md
    — 四步模式的深度解析
  • references/migration-guide.md
    — v3到v4的迁移指南