CSS

radix-ui

📒 @radix-ui 的作用和使用方式。

发布于 2026年5月30日0 views

@radix-ui 是一套无样式的 React UI 组件原语。

“无样式”是它最重要的特点:它不负责让组件变得好看,而是负责让组件“行为正确”。比如弹窗怎么打开关闭、键盘怎么操作、焦点怎么管理、屏幕阅读器怎么识别,这些复杂但很容易被忽略的细节,Radix UI 会帮你处理。

它解决什么问题

有些组件看起来简单,实际很容易写错。

比如 Dialog 弹窗:

  • 打开弹窗后,键盘焦点应该进入弹窗。
  • Esc 应该能关闭。
  • 弹窗打开时,背景内容不应该被误操作。
  • 屏幕阅读器需要知道这是一个弹窗。
  • 关闭后,焦点最好回到打开弹窗的按钮上。

再比如 Dropdown Menu:

  • 鼠标可以点击。
  • 键盘方向键可以移动。
  • Enter 可以选择。
  • 点击外部区域可以关闭。
  • 菜单定位不能乱飘。

这些都不是纯 CSS 能解决的。Radix UI 的作用就是把这些交互行为封装好,让开发者专心写业务和样式。

它具体做什么

Radix UI 提供很多底层组件,例如:

  • @radix-ui/react-dialog:弹窗。
  • @radix-ui/react-dropdown-menu:下拉菜单。
  • @radix-ui/react-popover:浮层。
  • @radix-ui/react-tabs:标签页。
  • @radix-ui/react-tooltip:提示气泡。
  • @radix-ui/react-select:选择器。
  • @radix-ui/react-switch:开关。

它们通常只提供结构和行为,不提供固定视觉风格。

也就是说,你拿到的是一个“会正确工作的组件骨架”,至于长什么样,由你用 Tailwind CSS、CSS Modules、普通 CSS 或其他方案来写。

基本使用方式

安装某个组件包:

npm install @radix-ui/react-dialog

使用 Dialog:

import * as Dialog from "@radix-ui/react-dialog";

export function DeleteDialog() {
  return (
    <Dialog.Root>
      <Dialog.Trigger>删除</Dialog.Trigger>

      <Dialog.Portal>
        <Dialog.Overlay className="fixed inset-0 bg-black/40" />
        <Dialog.Content className="fixed left-1/2 top-1/2 w-96 -translate-x-1/2 -translate-y-1/2 rounded-md bg-white p-6">
          <Dialog.Title>确认删除?</Dialog.Title>
          <Dialog.Description>
            删除后数据将无法恢复。
          </Dialog.Description>

          <Dialog.Close>取消</Dialog.Close>
          <button>确认删除</button>
        </Dialog.Content>
      </Dialog.Portal>
    </Dialog.Root>
  );
}

这段代码里:

  • Dialog.Root:管理整个弹窗状态。
  • Dialog.Trigger:触发打开弹窗的元素。
  • Dialog.Portal:把弹窗渲染到页面顶层,避免被父元素遮挡。
  • Dialog.Overlay:背景遮罩。
  • Dialog.Content:弹窗主体内容。
  • Dialog.Title / Dialog.Description:提供语义和无障碍信息。
  • Dialog.Close:关闭弹窗。

和 shadcn/ui 的关系

很多 shadcn/ui 组件底层都用了 Radix UI。

可以这样理解:

  • Radix UI:提供交互能力和无障碍能力。
  • shadcn/ui:把 Radix UI、Tailwind CSS 和项目组件组织方式包装成一套更好用的组件代码。

比如 shadcn/ui 的 Dialog 组件,底层通常就是基于 @radix-ui/react-dialog 封装的。

你平时开发时,不一定会直接写 Radix UI 原始组件。很多时候你会先用 shadcn/ui 提供的封装版本;只有当你要做高度自定义交互时,才直接使用 Radix UI。

什么时候直接用 Radix UI

适合:

  • 需要自己设计 UI 样式,但不想从零写复杂交互。
  • 项目有自己的设计系统。
  • 需要高度自定义弹窗、菜单、浮层、选择器等组件。
  • 希望组件支持键盘操作和无障碍体验。

不太适合:

  • 想要开箱即用的完整视觉组件库。
  • 不想自己写样式。
  • 非 React 项目。

使用建议

如果项目已经使用 shadcn/ui,优先使用 components/ui 里封装好的组件。

只有这些场景再直接使用 Radix UI:

  • shadcn/ui 没有提供对应组件。
  • 现有组件封装不满足业务需求。
  • 需要做一个项目自己的基础组件。

直接使用 Radix UI 时,建议把它再封装一层,放到项目的基础组件目录里,而不是在业务页面到处直接写 Radix UI 结构。

总结

@radix-ui 是 React 生态里非常适合做底层 UI 交互的组件原语。它不负责样式,但负责弹窗、菜单、浮层这类组件最难写对的行为细节;如果说 shadcn/ui 是“能直接用的组件源码”,Radix UI 就是这些复杂组件背后的交互发动机。