
关于
使用 Radix UI 原语构建无障碍设计系统。无头组件定制、主题策略和复合组件模式,面向生产级 UI 库。
name: radix-ui-design-system description: "使用 Radix UI 原语构建无障碍设计系统。无头组件自定义、主题策略和复合组件模式,用于生产级 UI 库。" risk: safe source: self date_added: "2026-02-27"
Radix UI 设计系统
使用 Radix UI 原语构建生产就绪、无障碍的设计系统,拥有完全的自定义控制和零样式预设。
概述
Radix UI 提供无样式、无障碍的组件(原语),你可以自定义以匹配任何设计系统。此技能指导你使用 Radix UI 构建可扩展的组件库,专注于无障碍优先设计、主题架构和可组合模式。
核心优势:
- 无头设计:完全的样式控制,无需对抗默认样式
- 内置无障碍:WAI-ARIA 合规、键盘导航、屏幕阅读器支持
- 可组合原语:从简单构建块构建复杂组件
- 框架无关:与 React 配合使用,但样式可在任何地方使用
适用场景
- 从零开始创建自定义设计系统
- 构建无障碍 UI 组件库
- 实现复杂交互组件(Dialog、Dropdown、Tabs 等)
- 从预设样式组件库迁移到无样式原语
- 使用 CSS 变量或 Tailwind 设置主题系统
- 需要完全控制组件行为和样式
- 构建需要 WCAG 2.1 AA/AAA 合规的应用
不适用场景
- 需要开箱即用的预设样式组件(使用 shadcn/ui、Mantine 等)
- 构建没有交互性的简单静态页面
- 项目不使用 React 16.8+(Radix 需要 hooks)
- 需要 React 以外框架的组件
核心原则
1. 无障碍优先
每个 Radix 原语都以无障碍为基础构建:
- 键盘导航:完整的键盘支持(Tab、方向键、Enter、Escape)
- 屏幕阅读器:正确的 ARIA 属性和实时区域
- 焦点管理:自动焦点捕获和恢复
- 禁用状态:正确处理 disabled 和 aria-disabled
规则:永远不要覆盖无障碍功能。增强,而非替换。
2. 无头架构
Radix 提供行为,你提供外观:
// Don't fight pre-styled components
<Button className="override-everything" />
// Radix gives you behavior, you add styling
<Dialog.Root>
<Dialog.Trigger className="your-button-styles" />
<Dialog.Content className="your-modal-styles" />
</Dialog.Root>
3. 组合优于配置
从简单原语构建复杂组件:
// Primitive components compose naturally
<Tabs.Root>
<Tabs.List>
<Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
<Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="tab1">Content 1</Tabs.Content>
<Tabs.Content value="tab2">Content 2</Tabs.Content>
</Tabs.Root>
快速开始
安装
# Install individual primitives (recommended)
npm install @radix-ui/react-dialog @radix-ui/react-dropdown-menu
# Or install multiple at once
npm install @radix-ui/react-{dialog,dropdown-menu,tabs,tooltip}
# For styling (optional but common)
npm install clsx tailwind-merge class-variance-authority
基本组件模式
每个 Radix 组件遵循此模式:
import * as Dialog from '@radix-ui/react-dialog';
export function MyDialog() {
return (
<Dialog.Root>
{/* Trigger the dialog */}
<Dialog.Trigger asChild>
<button className="trigger-styles">Open</button>
</Dialog.Trigger>
{/* Portal renders outside DOM hierarchy */}
<Dialog.Portal>
{/* Overlay (backdrop) */}
<Dialog.Overlay className="overlay-styles" />
{/* Content (modal) */}
<Dialog.Content className="content-styles">
<Dialog.Title>Title</Dialog.Title>
<Dialog.Description>Description</Dialog.Description>
{/* Your content here */}
<Dialog.Close asChild>
<button>Close</button>
</Dialog.Close>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
}
主题策略
策略 1:CSS 变量(框架无关)
最适合:最大可移植性,SSR 友好
/* globals.css */
:root {
--color-primary: 220 90% 56%;
--color-surface: 0 0% 100%;
--radius-base: 0.5rem;
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
}
[data-theme="dark"] {
--color-primary: 220 90% 66%;
--color-surface: 222 47% 11%;
}
// Component.tsx
<Dialog.Content
className="
bg-[hsl(var(--color-surface))]
rounded-[var(--radius-base)]
shadow-[var(--shadow-lg)]
"
/>
策略 2:Tailwind + CVA(Class Variance Authority)
最适合:Tailwind 项目,变体密集的组件
兼容工具
Claude CodeCursor
标签
前端开发