关于 shadcn-tailwind
面向构建无障碍界面的 Tailwind CSS v4 与 shadcn/ui 样式技能,适用于前端开发者。重点涵盖 CSS 优先配置、语义化主题及组件实现规范。
主要功能
- 01Tailwind v4 CSS 优先配置
- 02shadcn/ui 组件模式
- 03语义化颜色与主题
- 04响应式及容器查询
- 05无障碍与动画规范
适用场景
- 01将旧配置迁移到 CSS 优先模式
- 02实现支持暗色模式的界面
- 03按规范编写 shadcn/ui 组件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tenequm/ skills --skill shadcn-tailwind安装后在 Claude Code 中输入/shadcn-tailwind确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.txtreferences/components.mdtheming.md详细介绍
使用 Tailwind CSS 设置样式
使用 Tailwind CSS v4 工具类和 shadcn/ui 组件模式构建无障碍 UI。Tailwind v4 仅使用 CSS 优先配置——切勿创建或修改 tailwind.config.js/tailwind.config.ts。 支持 Radix UI(默认)或 Base UI 作为基础组件库。
关键规则
不使用 tailwind.config.js——仅使用 CSS 优先配置
Tailwind v4 在 CSS 中配置所有内容。迁移任何 JS/TS 配置:
theme.extend.colors→@theme { --color-*: ... }plugins→@plugin "..."或@utilitycontent→@source "..."tailwindcss-animate→@import "tw-animate-css"@layer utilities→@utility name { ... }
始终使用语义颜色令牌
// CORRECT - respects themes and dark mode
<div className="bg-primary text-primary-foreground">
// WRONG - breaks theming
<div className="bg-blue-500 text-white">
始终将 bg-* 与 text-*-foreground 配对。请参阅主题设置,了解如何扩展 success/warning/info。
切勿动态构建类名
// 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]}>
cn() 合并顺序
先放默认值,最后放使用者的 className(tailwind-merge 后者优先):
className={cn(buttonVariants({ variant, size }), className)} // correct
className={cn(className, buttonVariants({ variant, size }))} // wrong
动画性能
// 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">
@theme 与 @theme inline
@theme- 静态令牌,可由插件覆盖@theme inline- 引用 CSS 变量,随深色模式变化
@theme { --color-brand: oklch(0.6 0.2 250); } /* static */
@theme inline { --color-primary: var(--primary); } /* dynamic */
有关更多注意事项,请参阅 components.md;有关颜色系统参考,请参阅 theming.md。
核心模式
用于主题设置的 CSS 变量
shadcn/ui 使用映射到 Tailwind 工具类的语义 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);
}
在组件中使用:
// 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">
组件编写模式
组件使用普通函数和 data-slot 属性(React 19 - 无需 forwardRef):
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>
使用 data-icon 设置图标间距:
<Button>
<Spinner data-icon="inline-start" />
Generating...
</Button>
<Button>
<CheckIcon data-slot="icon" />
Save Changes
</Button>
响应式设计
移动优先断点:
// 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">
容器查询
Tailwind v4 原生支持,无需插件:
<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">
深色模式
// 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
常见组件模式
卡片
<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>
表单字段
<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>
徽章
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",
},
},
}
)
布局模式
居中布局
<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>
侧边栏布局
<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>
仪表盘网格
<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>
无障碍模式
焦点可见状态
<button className="focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
仅供屏幕阅读器使用
<span className="sr-only">Close dialog</span>
禁用状态
<button className="disabled:cursor-not-allowed disabled:opacity-50" disabled>
Tailwind v4 功能
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";
@theme 指令
@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);
}
动画
@import "tw-animate-css";
<div className="animate-fade-in">
<div className="animate-slide-in-from-top">
v4.1 功能
// 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>
v4.2 功能(2026 年 2 月)
// 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">
弃用说明:start-*/end-* 已弃用,改用 inset-s-*/inset-e-*。
OKLCH 颜色
所有 shadcn/ui 颜色均使用 OKLCH 格式:oklch(lightness chroma hue)。明度范围为 0-1,色度范围为 0-0.4(0 = 灰色),色相范围为 0-360。基础调色板:Neutral、Zinc、Slate、Stone、Gray。完整调色板和 OKLCH 参考请参阅 theming.md。
最佳实践
优先使用语义颜色
// Good - uses theme
<div className="bg-background text-foreground">
// Avoid - hardcoded
<div className="bg-white text-black dark:bg-zinc-950">
将相关工具类分组
<div className="
flex items-center justify-between
rounded-lg border
bg-card text-card-foreground
p-4 shadow-sm
hover:bg-accent
">
避免使用任意值
// Prefer design tokens
<div className="p-4 text-sm">
// Avoid when unnecessary
<div className="p-[17px] text-[13px]">
安装与 CLI
# Create new project with visual style + primitive selection
npx shadcn create
# Initialize in existing project
pnpm dlx shadcn@latest init
# Add components
pnpm dlx shadcn@latest add button card form
# Add from community registries
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
# Add MCP server for AI integration
npx shadcn@latest mcp init
# Update existing components
pnpm dlx shadcn@latest add button --overwrite
视觉样式
npx shadcn create 提供 5 种内置视觉样式:
- Vega - 经典 shadcn/ui 外观
- Nova - 紧凑,减少内边距
- Maia - 柔和圆润,间距宽松
- Lyra - 方正锐利,适合搭配等宽字体
- Mira - 密集布局,适用于数据密集型界面
这些样式会重写组件代码(而不只是 CSS 变量),使其符合所选样式。
故障排除
**颜色未更新:**检查 globals.css 中的 CSS 变量 → 确认 @theme inline 包含相应映射 → 清除构建缓存。
**加载时闪现深色模式:**在 <html> 标签上添加 suppressHydrationWarning,并确保 ThemeProvider 使用 attribute="class" 包裹应用。
**发现 tailwind.config.js:**将其删除。运行 npx @tailwindcss/upgrade,自动迁移为 CSS 优先配置。所有自定义内容都应通过 @theme、@utility、@plugin 放在 CSS 文件中。
**未检测到类名:**检查 @source 指令是否涵盖组件路径。切勿动态构建类名(参阅“关键规则”)。
组件模式
有关详细的组件模式,请参阅 components.md:
- 组合:asChild 模式、data-slot 属性
- 排版:标题层级、正文样式、行内代码
- 表单:React Hook Form + Zod,使用 FieldSet/FieldGroup 的 Field 组件
- 图标:带有 data-icon 属性的 Lucide 图标
- 输入框:OTP、文件、分组输入框
- 对话框:模态框模式与组合
- 数据表格:TanStack 表格集成
- 提示消息:Sonner 通知
- 易错点:cn() 顺序、表单 defaultValues、对话框嵌套、sticky、服务端/客户端
资源
完整的颜色系统参考请参阅 theming.md:
@theme与@theme inline(对暗色模式至关重要)- 状态颜色扩展(success、warning、info)
- Z-index 层级与动画令牌
- 所有基础调色板(Neutral、Zinc、Slate、Stone、Gray)
总结
关键概念:
- 仅使用 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 作为基础组件库
此技能面向 Tailwind CSS v4.2 和 shadcn/ui。组件专属示例请参阅 components.md。颜色系统请参阅 theming.md。