tailwind-shadcn
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTailwind + shadcn/ui
Tailwind + shadcn/ui
Apply these patterns whether you're building new UI from scratch or refactoring existing code — the rules are the same either way.
无论你是在从零构建新 UI,还是重构现有代码,都应应用这些模式——两种场景的规则完全相同。
Detect framework first
首先检测框架
This skill serves two ecosystems. Before doing anything, read to detect which one you're in:
package.json- /
reactpresent → React mode. Primitive layer is Base UI; the CLI is the officialreact-dom. Gather project context by running:npx shadcn@latestKey fields:jsonnpx shadcn@latest info --json(v4 usestailwindVersion; v3 uses@theme inline),tailwind.config.js(always edit this file for CSS variables — never create a new one),tailwindCssFile(use the actual alias prefix for imports, never hardcode),aliases(the primitive layer).base - present → Solid mode. Primitive layer is Kobalte (Zaidan components); the CLI is
solid-js(much thinner — nonpx shadcn-solid@latest/info/search). Gather project context by readingdocs+ui.config.json. See references/cli-shadcn-solid.md and references/primitives-solid.md.package.json
此 skill 服务于两个生态。在开始任何操作之前,先读取 ,以确定当前使用的是哪一个:
package.json- 存在 /
react→ React 模式。 Primitive 层为 Base UI;CLI 为官方react-dom。运行以下命令获取项目上下文:npx shadcn@latest关键字段:jsonnpx shadcn@latest info --json(v4 使用tailwindVersion;v3 使用@theme inline)、tailwind.config.js(始终编辑此文件来管理 CSS variables——不要创建新文件)、tailwindCssFile(导入时使用实际的 alias 前缀,不要硬编码)、aliases(primitive 层)。base - 存在 → Solid 模式。 Primitive 层为 Kobalte(Zaidan components);CLI 为
solid-js(功能更精简——没有npx shadcn-solid@latest/info/search)。读取docs和ui.config.json以获取项目上下文。请参阅 references/cli-shadcn-solid.md 和 references/primitives-solid.md。package.json
Framework mode
框架模式
| Concern | React mode | Solid mode |
|---|---|---|
| Primitive layer | Base UI — see "Primitive layer APIs" below | Kobalte (Zaidan) — see references/primitives-solid.md |
| CLI | | |
| JSX class attribute | | |
| Component composition | | |
| Lists | | |
Normalization note (Solid mode): the styling discipline below and the shared references (, , ) use React () syntax in their examples. In Solid mode, read every as , read + as , and ignore React-only constructs ( types, , ). See references/primitives-solid.md for the Solid equivalents. The Tailwind/token discipline itself is identical in both modes.
theming.mdresponsive.mdcva.mdclassNameclassNameclass.map(...)key<For each>React.*asChildSlot| 关注点 | React 模式 | Solid 模式 |
|---|---|---|
| Primitive 层 | Base UI——请参阅下方的“Primitive 层 API” | Kobalte(Zaidan)——请参阅 references/primitives-solid.md |
| CLI | | |
| JSX class 属性 | | |
| 组件组合 | | |
| 列表 | | |
规范化说明(Solid 模式): 下方的样式规范以及共享参考文档(、、)在示例中使用 React()语法。在 Solid 模式下,将所有 视为 ,将 + 视为 ,并忽略仅适用于 React 的结构( 类型、、)。Solid 对应写法请参阅 references/primitives-solid.md。两种模式下的 Tailwind/token 规范完全相同。
theming.mdresponsive.mdcva.mdclassNameclassNameclass.map(...)key<For each>React.*asChildSlotPrinciples
原则
- Reusability first — exhaust existing options before writing any inline/custom component. Work down this ladder in order:
- Search what the project already has. Scan the UI components directory (in React mode; the components dir in Solid mode) for an existing component that fits.
resolvedPaths.ui - Extend what exists. If an existing component nearly fits and it makes semantic sense, reuse it. Add a new variant only when the styling will be reused in more than one place — for a one-off, prefer composition or a
cvaoverride. Don't reach for a variant by default; overusingclassNameadds complexity. See references/cva.md.cva - Bring in an available component. Check the registry before writing custom UI — (React); browse the shadcn-solid catalog (Solid, no
npx shadcn@latest search). Check community registries too.search - Only then write custom code, and consult the component docs first (in React mode) for the recommended reusable pattern.
npx shadcn@latest docs <component>
- Search what the project already has. Scan the UI components directory (
- Compose, don't reinvent. Settings page = Tabs + Card + form controls. Dashboard = Sidebar + Card + Chart + Table.
- Use built-in variants before custom styles. ,
variant="outline", etc.size="sm" - Use semantic colors. ,
bg-primary— never raw values liketext-muted-foreground.bg-blue-500
- 优先复用——在编写任何内联/自定义组件之前,充分探索现有选项。 按以下顺序逐级处理:
- 搜索项目中已有的内容。 扫描 UI components 目录(React 模式下的 ;Solid 模式下的 components 目录),查找符合需求的现有组件。
resolvedPaths.ui - 扩展已有内容。 如果现有组件基本符合需求,并且从语义上看适合复用,就直接使用。只有当某项样式会在多个位置复用时,才新增 variant;对于一次性需求,优先使用组合或
cva覆盖。不要默认使用 variant;过度使用className会增加复杂度。请参阅 references/cva.md。cva - 引入已有组件。 编写自定义 UI 之前先检查 registry——React 使用 ;Solid 则浏览 shadcn-solid catalog(没有
npx shadcn@latest search)。同时检查社区 registry。search - 只有在以上方式都不适用时才编写自定义代码,并先查阅组件文档(React 模式使用 ),以了解推荐的可复用模式。
npx shadcn@latest docs <component>
- 搜索项目中已有的内容。 扫描 UI components 目录(React 模式下的
- 组合,不要重新发明。 设置页面 = Tabs + Card + 表单控件。仪表盘 = Sidebar + Card + Chart + Table。
- 优先使用内置 variants,而不是自定义样式。 例如 、
variant="outline"。size="sm" - 使用语义化颜色。 使用 、
bg-primary——不要使用text-muted-foreground之类的原始值。bg-blue-500
Critical Rules
关键规则
These rules are always enforced.
以下规则始终必须遵守。
Colors
颜色
- Never use raw Tailwind palette values (,
text-blue-500) in application code.bg-emerald-600 - Never hardcode hex/rgb/oklch values inline in className strings.
- Use semantic tokens for all color decisions: ,
bg-primary,text-destructive.border-border - For status indicators with no matching token, use variants first. If a reusable semantic token is needed (e.g.
Badge), add it to the theme.--success
- 在应用代码中,绝不使用原始 Tailwind palette 值(、
text-blue-500)。bg-emerald-600 - 绝不在 className 字符串中内联硬编码 hex/rgb/oklch 值。
- 所有颜色决策都应使用语义化 tokens:、
bg-primary、text-destructive。border-border - 如果状态指示器没有对应的 token,应先使用 variants。如果确实需要可复用的语义化 token(例如
Badge),则将其添加到主题中。--success
Spacing & layout
间距与布局
- No or
space-x-*. Usespace-y-*+flexinstead.gap-*→space-y-4.flex flex-col gap-4 - when width = height.
size-*notsize-10.w-10 h-10 - not
truncate.overflow-hidden text-ellipsis whitespace-nowrap
- 不要使用 或
space-x-*。 改用space-y-*+flex。gap-*→space-y-4。flex flex-col gap-4 - 宽度等于高度时使用 。 使用
size-*,不要使用size-10。w-10 h-10 - 使用 ,不要使用
truncate。overflow-hidden text-ellipsis whitespace-nowrap
Component styling
组件样式
- is for layout, not overrides. Acceptable:
className. Not acceptable:max-w-md mx-auto mt-4.bg-blue-100 text-blue-900 font-bold - Built-in variants first. Exhaust ,
variant="outline",variant="destructive"before adding new ones.size="sm" - Add a new variant sparingly — only when a styling pattern repeats (used in more than one place) and no built-in fits. Edit the component source using . Not every component needs variants; a one-off doesn't warrant one. See references/cva.md.
cva
- 用于布局,而不是覆盖样式。 可接受:
className。不可接受:max-w-md mx-auto mt-4。bg-blue-100 text-blue-900 font-bold - 优先使用内置 variants。 在添加新 variant 前,应充分尝试 、
variant="outline"、variant="destructive"。size="sm" - 谨慎添加新 variant——仅当同一种样式模式在多个位置重复出现,并且没有合适的内置 variant 时才添加。使用 修改组件源代码。不是每个组件都需要 variant;一次性需求不足以成为添加 variant 的理由。请参阅 references/cva.md。
cva
Class merging
Class 合并
- for all conditional or merged classes. No
cn()in className.${isActive ? 'bg-primary' : 'bg-muted'} - No manual on overlay components (Dialog, Sheet, Popover, Tooltip, Drawer). They manage their own stacking.
z-index - No manual overrides. Semantic tokens handle theme switching via CSS variables.
dark:
- 所有条件类名或需要合并的类名都使用 。 不要在 className 中使用
cn()。${isActive ? 'bg-primary' : 'bg-muted'} - 不要在 overlay 组件上(Dialog、Sheet、Popover、Tooltip、Drawer)手动设置 。 它们会自行管理层级。
z-index - 不要手动编写 覆盖样式。 语义化 tokens 会通过 CSS variables 处理主题切换。
dark:
CSS Architecture
CSS 架构
Variables at :root
:root在 :root
中定义变量
:rootAll color tokens are CSS custom properties on in the global CSS file ( from project context). Never scatter variable definitions across component files.
:roottailwindCssFilecss
: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);
/* ... see references/theming.md for the full token set */
}OKLCH: — perceptually uniform, so equal chroma values look equally saturated across hues. Prefer it over HSL.
oklch(lightness chroma hue)所有颜色 tokens 都是全局 CSS 文件(项目上下文中的 )中 上的 CSS custom properties。不要将变量定义分散到各个组件文件中。
tailwindCssFile:rootcss
: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);
/* ... see references/theming.md for the full token set */
}OKLCH: ——在感知上保持均匀,因此不同 hue 上相同的 chroma 值看起来具有相同的饱和度。优先使用 OKLCH,而不是 HSL。
oklch(lightness chroma hue)Map variables to Tailwind
将变量映射到 Tailwind
With Tailwind v4, register every CSS variable via :
@theme inlinecss
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
/* ... see references/theming.md for the full mapping */
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
}使用 Tailwind v4 时,通过 注册每个 CSS variable:
@theme inlinecss
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
/* ... see references/theming.md for the full mapping */
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
}Apply base styles
应用基础样式
css
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}Do not double-wrap: inside blocks, use utility classes () or directly — never .
@layerbg-backgroundvar(--background)oklch(var(--background))css
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}不要重复包裹:在 块内,直接使用 utility classes()或 ——绝不要使用 。
@layerbg-backgroundvar(--background)oklch(var(--background))Adding Theme Tokens
添加主题 Tokens
Before reaching for an arbitrary value or a raw Tailwind color:
Need a color or spacing unit →
Does a semantic token cover it? → use it
Does a Tailwind default utility cover it? → use it
Is this a one-off pixel nudge? → arbitrary is fine: [3px]
Will this value appear in more than once? → add a tokenSee references/theming.md for the full custom color and spacing token workflow, naming conventions, and the complete token table.
在考虑使用任意值或原始 Tailwind 颜色之前:
Need a color or spacing unit →
Does a semantic token cover it? → use it
Does a Tailwind default utility cover it? → use it
Is this a one-off pixel nudge? → arbitrary is fine: [3px]
Will this value appear in more than once? → add a token有关完整的自定义颜色和间距 token 工作流、命名约定及完整 token 表,请参阅 references/theming.md。
Components & CLI
组件与 CLI
Run all CLI commands with the project's package runner (/npx/pnpm dlx) — frombunx --bunin project context.packageManager
使用项目的 package runner(/npx/pnpm dlx)运行所有 CLI 命令——具体方式由项目上下文中的bunx --bun决定。packageManager
React mode
React 模式
bash
npx shadcn@latest add button card dialog
npx shadcn@latest add @magicui/shimmer-button # from a community registryPreview before installing with / — see references/cli.md. Full registry surface available: , , .
--dry-run--diffsearchdocsinfobash
npx shadcn@latest add button card dialog
npx shadcn@latest add @magicui/shimmer-button # from a community registry安装前使用 / 预览变更——请参阅 references/cli.md。完整的 registry 功能包括:、、。
--dry-run--diffsearchdocsinfoSolid mode
Solid 模式
bash
npx shadcn-solid@latest add button card dialogThe shadcn-solid CLI is thin — only , , and . There is no , , , , or / flag. Browse component docs at zaidan.carere.dev / shadcn-solid.com in the browser instead, and preview changes via the command or by reading the copy-paste source. See references/cli-shadcn-solid.md.
initadddiffinfosearchdocs--dry-run--diff--viewdiffAfter adding (either mode), always read the added files and verify correct composition: check for missing sub-components, incorrect nesting, and violations of the Critical Rules above. In Solid mode, also apply the bundle-weight check from references/primitives-solid.md — trim or hand-roll components that pull Kobalte for no a11y benefit.
bash
npx shadcn-solid@latest add button card dialogshadcn-solid CLI 非常精简——仅支持 、 和 。不提供 、、、 或 / flag。请改为在浏览器中访问 zaidan.carere.dev / shadcn-solid.com 浏览组件文档,并通过 命令或阅读可复制粘贴的源代码来预览变更。请参阅 references/cli-shadcn-solid.md。
initadddiffinfosearchdocs--dry-run--diff--viewdiff添加组件后(两种模式均适用),始终读取新增文件并验证组合是否正确:检查是否缺少子组件、嵌套是否错误,以及是否违反上述关键规则。在 Solid 模式下,还应执行 references/primitives-solid.md 中的 bundle 体积检查——对于没有带来 a11y 收益却引入 Kobalte 的组件,应精简或自行实现。
Primitive layer APIs
Primitive 层 API
React mode — Base UI. Key differences from Radix to keep in mind:
- Composition: use the prop, not
render.asChild<DialogTrigger render={<Button />}>Open</DialogTrigger> - Select: requires an prop on the root;
itemsfor placeholder isdefaultValuein the items array.null - ToggleGroup / Accordion: use boolean instead of
multiple;type="multiple"is always an array.defaultValue - Slider: accepts a plain number for a single thumb (), not an array.
defaultValue={50}
Solid mode — Kobalte. The primitive APIs, composition ( prop), and the bundle-weight discipline that governs when to reach for a Kobalte primitive at all are covered in references/primitives-solid.md. Read it before adding any interactive Solid component.
asReact 模式——Base UI。 需要注意与 Radix 的主要差异:
- **组合:**使用 prop,而不是
render。asChild<DialogTrigger render={<Button />}>Open</DialogTrigger> - **Select:**root 上必须提供 prop;在
items数组中,用于占位符的items为defaultValue。null - **ToggleGroup / Accordion:**使用 boolean,而不是
multiple;type="multiple"始终为数组。defaultValue - **Slider:**单 thumb 时接受普通 number(),而不是数组。
defaultValue={50}
Solid 模式——Kobalte。 Primitive API、组合方式( prop)以及用于决定何时采用 Kobalte primitive 的 bundle 体积规范,均在 references/primitives-solid.md 中介绍。添加任何 Solid 交互式组件之前,请先阅读该文档。
asWorkflow
工作流
- Detect framework & get project context — read (React vs Solid), then gather context per "Detect framework first" above (React:
package.json; Solid: readnpx shadcn@latest info --json+ui.config.json).package.json - Check installed components first — before running , check what's already in the UI directory (
addin React; the components dir fromresolvedPaths.uiin Solid). Don't import components that haven't been added, and don't re-add ones already installed.ui.config.json - Find the component —
- React: to discover components (community registries too).
npx shadcn@latest search - Solid: no — browse zaidan.carere.dev / shadcn-solid.com in the browser.
search
- React:
- Get docs and examples —
- React: for URLs, then fetch; use
npx shadcn@latest docs <component>/--dry-runto preview.--diff - Solid: no /preview flags — read the docs site, and preview via
docsor by reading the copy-paste source afterdiff.add
- React:
- Install — (React) or
npx shadcn@latest add <component>(Solid).npx shadcn-solid@latest add <component> - Review added files — read every added file; fix composition issues, icon imports, and alias paths. Solid: also run the bundle-weight check (references/primitives-solid.md) — hand-roll or trim components that pull Kobalte without an a11y payoff.
- Apply styling rules — use semantic tokens, , the
cn()variant pattern, and mobile-first responsive styles per the Critical Rules above.cva - Format & lint — detect the project formatter from scripts and run it on every changed file. A non-zero exit is a blocking failure — do not declare the task done until it passes. See references/formatting.md for the detection heuristic and per-tool commands.
package.json
- 检测框架并获取项目上下文——读取 (判断 React 还是 Solid),然后按照上文“首先检测框架”中的方式获取上下文(React:
package.json;Solid:读取npx shadcn@latest info --json+ui.config.json)。package.json - 首先检查已安装的组件——运行 之前,检查 UI 目录中已经有哪些内容(React 模式下的
add;Solid 模式下resolvedPaths.ui指定的 components 目录)。不要导入尚未添加的组件,也不要重复添加已有组件。ui.config.json - 查找组件——
- React: 使用 发现组件,也可搜索社区 registry。
npx shadcn@latest search - Solid: 没有 ——请在浏览器中浏览 zaidan.carere.dev / shadcn-solid.com。
search
- React: 使用
- 获取文档和示例——
- React: 使用 获取 URL,然后获取文档;使用
npx shadcn@latest docs <component>/--dry-run预览。--diff - Solid: 没有 或预览 flags——请阅读文档网站,并通过
docs或在diff后阅读可复制粘贴的源代码进行预览。add
- React: 使用
- 安装——React 使用 ,Solid 使用
npx shadcn@latest add <component>。npx shadcn-solid@latest add <component> - 审查新增文件——读取每个新增文件;修复组合问题、图标导入和 alias 路径。Solid: 还要执行 bundle 体积检查(references/primitives-solid.md)——对于没有 a11y 收益却引入 Kobalte 的组件,应自行实现或精简。
- 应用样式规则——按照上述关键规则,使用语义化 tokens、、
cn()variant 模式以及 mobile-first 响应式样式。cva - 格式化与 lint——从 scripts 中检测项目 formatter,并对每个变更文件运行它。非零退出码属于阻断性失败——在通过检查前,不要将任务标记为完成。有关检测启发式方法和各工具的运行命令,请参阅 references/formatting.md。
package.json
CVA vs cn
CVA 与 cn
See references/cva.md for the full guide.
Quick rule:
- lives in component definitions — it encodes what variants a component supports.
cva - lives at call sites — it merges incoming
cnwith cva output and handles conditionals.className
tsx
const buttonVariants = cva("inline-flex items-center ...", {
variants: { variant: { default: "bg-primary ...", outline: "border ..." } },
defaultVariants: { variant: "default" },
});
function Button({ className, variant, ...props }) {
return (
<button className={cn(buttonVariants({ variant }), className)} {...props} />
);
}有关完整指南,请参阅 references/cva.md。
快速规则:
- 位于组件定义中——用于编码组件支持的 variants。
cva - 位于调用位置——用于合并传入的
cn与 cva 输出,并处理条件类名。className
tsx
const buttonVariants = cva("inline-flex items-center ...", {
variants: { variant: { default: "bg-primary ...", outline: "border ..." } },
defaultVariants: { variant: "default" },
});
function Button({ className, variant, ...props }) {
return (
<button className={cn(buttonVariants({ variant }), className)} {...props} />
);
}Responsive Design
响应式设计
See references/responsive.md for breakpoint reference and patterns.
Key rules:
- Write base (mobile) styles first, then layer breakpoint modifiers upward: ,
sm:,md:.lg: - Flex by default. for vertical stacks,
flex flex-colfor horizontal.flex - Grid only when genuinely two-dimensional — real rows and columns (data tables, calendar grids). Never use grid as a substitute for flex on a single axis.
tsx
// Good: flex column on mobile, row on desktop
<div className="flex flex-col gap-4 md:flex-row md:items-center">有关 breakpoint 参考和设计模式,请参阅 references/responsive.md。
关键规则:
- 先编写基础(mobile)样式,然后逐层添加 breakpoint 修饰符:、
sm:、md:。lg: - 默认使用 Flex。 垂直堆叠使用 ,水平排列使用
flex flex-col。flex - 仅在真正需要二维布局时使用 Grid——即同时存在实际的行和列(数据表格、日历网格)。绝不要在单一轴向上使用 Grid 代替 Flex。
tsx
// Good: flex column on mobile, row on desktop
<div className="flex flex-col gap-4 md:flex-row md:items-center">References
参考文档
Shared (both modes):
- references/theming.md — Full OKLCH token table, mapping, adding custom tokens
@theme inline - references/cva.md — vs
cva, variant patterns, compound variantscn - references/responsive.md — Breakpoints, flex/grid decision guide, common responsive patterns
React mode:
- references/cli.md — : adding, previewing, searching registries, docs, project info
npx shadcn@latest
Solid mode:
- references/primitives-solid.md — Kobalte/Zaidan authoring idioms, primitive APIs, and the bundle-weight selective-adoption discipline
- references/cli-shadcn-solid.md — : the thin CLI surface, Zaidan delivery, browser-docs workflow
npx shadcn-solid@latest
Tooling:
- references/formatting.md — Formatter detection heuristic and per-tool commands (Biome, Prettier+ESLint, ESLint-only)
两种模式共享:
- references/theming.md——完整的 OKLCH token 表、映射及添加自定义 tokens
@theme inline - references/cva.md——与
cva、variant 模式及 compound variantscn - references/responsive.md——breakpoints、Flex/Grid 决策指南及常见响应式模式
React 模式:
- references/cli.md——:添加、预览、搜索 registry、文档及项目信息
npx shadcn@latest
Solid 模式:
- references/primitives-solid.md——Kobalte/Zaidan 编写惯例、primitive API 及 bundle 体积选择性采用规范
- references/cli-shadcn-solid.md——:精简的 CLI 功能、Zaidan 分发方式及浏览器文档工作流
npx shadcn-solid@latest
工具链:
- references/formatting.md——formatter 检测启发式方法及每种工具的运行命令(Biome、Prettier+ESLint、仅 ESLint)