跳至正文
React — shadcn/ui 与 HeroUI v3 的 Design Tokens:覆盖范围、项目够用程度与网站设计边界

shadcn/ui 与 HeroUI v3 的 Design Tokens:覆盖范围、项目够用程度与网站设计边界

shadcn/ui Theming · HeroUI Theming

HeroUI Colors:用户提供的入口 · Default Theme Variables · Shared Theme Utilities

AI 参与说明(Agent:Codex):本文通过 Context7、官方文档和固定提交的公开 CSS 源码整理,比较 shadcn/ui 与 HeroUI v3 的主题变量、基础尺度和组件状态,并给出网站设计的实践建议。资料核验日期为 2026-10-22;项目是否够用及选型建议属于基于这些证据的工程判断。执行入口 Codex Desktop;本轮模型完整标识与 reasoning effort 未取得任务级运行记录。中文正文按项目 humanizer-zh 编辑。

如果比较默认提供的通用语义角色、表单细分、反馈状态和全局视觉参数,HeroUI v3 覆盖更广。shadcn/ui 的核心主题更精简,但自带图表和侧栏专用角色,还能结合 Tailwind 与可选的 Typeset 完成常见网站。一般项目用任意一套作为基础通常都够,真正需要补的是项目自己的布局、排版、业务语义和使用规则。

这里的“够用”指能够用少量一致的扩展完成网站,不表示只改几个变量就完成网站设计,也不表示组件库替项目完成了无障碍验收。

比较范围与术语

本文比较 HeroUI v3 开源默认样式与当前 shadcn/ui Theming 约定。不把 HeroUI v2 的主题插件、HeroUI Native 或 HeroUI Pro 的额外 token 混入开源默认体系。shadcn/ui 则区分核心主题、Tailwind 基础尺度及可选的 Typeset。

英文术语中文名称简要解释
Design Token设计令牌为可复用设计值命名,例如主行动颜色、圆角或阴影
Primitive Token基础令牌描述基础值,例如某个蓝色、间距尺度或字体;本文采用的分析分层
Semantic Token语义令牌按用途命名,例如危险操作颜色;同样的角色可在深浅色下取不同值
Component Token组件令牌面向具体组件或部件的值,例如按钮按下背景;局部实现变量未必是稳定的公开接口
Recipe样式配方将尺寸、颜色、状态选择器等组合成组件样式的规则
Utility工具类对应某项样式的 CSS 类,例如 bg-accent 或 gap-4
Typeset排版体系此处特指 shadcn/typeset,为 HTML 与 Markdown 内容组织字体和阅读节奏

The number of CSS variables is not a measure of design-system completeness. Semantic coverage and actual component consumption matter more than raw counts.

CSS 自定义属性是实现 Design Token 的一种方式。一个属性也可能只是别名、中间计算值或组件内部变量;反过来,某种视觉状态可以由 Recipe 计算,并不一定拥有独立变量。DTCG Format 2025.10描述了 token 的值、类型和引用方式,但不能据此认定这两个库已经实现完整的 DTCG 交换格式。该文档属于 Community Group Report,并非 W3C Standard。

本次源码快照:

对象核验范围
shadcn/ui2026-10-22 的 Theming、Typeset 文档;公开源码提交 ba1503c64472b82256d9de95e2e62c5901a38e8b
HeroUI@heroui/styles 3.2.6 对应的 v3 分支快照 d814c204a92464ca02eb229c384a4a982d1ab398;默认变量、共享映射及相关组件 CSS

shadcn/ui 组件由项目持有,已有项目未必已经采用当前文档中的全部变量和 Recipe;比较结果不能直接当作升级后会自动发生的变化。

先把三层分开

讨论覆盖范围时,需要分别检查:

  1. 基础尺度:颜色原值、字号、间距、尺寸、阴影、断点等。两者都大量承接 Tailwind,不能把这一层只算给某一方。
  2. 语义角色:品牌强调、弱化文字、浮层、表单、成功或危险等。这是默认 token 体系最值得直接比较的部分。
  3. 组件 Recipe:按钮如何变大、输入框如何显示错误、按下时是否缩放。很多细节写在组件样式中,未提升为全局 token。

例如 gap-4 表示从间距尺度取值;“表单行间距统一用多少”是项目规则;“按钮内部的图标间距取哪一档”属于组件 Recipe。这三件事相关,但不能互相替代。

覆盖范围对照

下表中的“默认”专指上述核验范围,不限制项目自行扩展。

维度shadcn/uiHeroUI v3 开源默认体系判断
页面基础色background、foreground相同角色,另有背景 secondary、tertiary、inverse 派生值HeroUI 更细
内容表面card / card-foreground,另有 muted 等辅助表面surface、surface-secondary、surface-tertiary,各有 foregroundHeroUI 的通用层级更明确
浮层popover / popover-foreground;遮罩在组件 Recipe 中定义overlay / overlay-foreground、backdropHeroUI 提供更多全局角色
主强调与辅助填充primary、secondary、accent 等配对角色accent、default 及各自 foreground、hover、soft 系列命名模型不同,不能只比较数量
成功、警告、危险核心默认有 destructive;success、warning、info 需扩展或来自其他组件方案success、warning、danger 及 foreground、hover、soft 系列;默认也没有独立 infoHeroUI 更全
弱化文字、链接、焦点muted-foreground、ring;链接常复用现有角色muted、link、focusHeroUI 更显式
表单颜色input、border、ring,配合 Recipe 处理背景、占位和 invalid独立 field 背景、文字、占位、边框、hover、focus 及边框状态HeroUI 明显更细
边框与分隔线border,另有 sidebar 专用 borderborder 与 separator 分开,均有 secondary、tertiaryHeroUI 更细
图表chart-1 至 chart-5,可继续扩展 ChartConfig开源默认主题文件没有对应 chart 系列shadcn 默认更直接
侧栏独立 sidebar 背景、文字、强调、选中、边框、焦点,共 8 个颜色变量开源默认没有 sidebar 专用语义分组shadcn 默认更直接
圆角根 radius 派生 sm 至 4xl根 radius 派生 xs 至 4xl,另有 field radius都能统一;HeroUI 多一组表单控制
阴影使用 Tailwind 阴影尺度与组件 Recipe额外提供 surface、overlay、field 角色阴影,深浅色可不同HeroUI 语义控制更方便
间距与尺寸Tailwind 尺度,组件选择 padding、gap、heightspacing 根值与 Tailwind 尺度,组件也有尺寸 Recipe都具备基础能力;都不替网站决定布局
字体与正文排版Tailwind;另有可选 Typeset 的 body、heading、mono 与阅读节奏这两个主题文件没有独立 font、text 角色体系,主要使用 Tailwind 与组件 Recipe不能宣称 HeroUI 排版全面领先
动效组件 transition、duration、animation 与样式工具额外提供多组 easing、若干 animation、Skeleton 模式和 Tooltip 延迟HeroUI 暴露更多全局参数;都需项目编排
禁用与光标多在 Recipe 中使用 opacity、pointer 等规则有 disabled opacity、交互与禁用 cursor 变量HeroUI 更集中
滚动条与浮层层级主要由具体组件或项目规则决定有 scrollbar 系列;base.css 另有 overlay、toast z-indexHeroUI 提供更多控制点,仍需网站层级规则
深浅色与扩展同名变量在 .dark 覆写;可增加变量和 Utilityclass / data-theme 切换;CSS 变量与 BEM 覆盖;可自定义主题两者都能扩展,不存在默认清单形成的硬上限

证据入口:shadcn Theming、Typeset、Nova 组件 Recipe、HeroUI 默认变量、共享映射、base.css。

为什么不直接比较“总共有多少 token”

按当前 shadcn Theming 页的默认清单去重,得到 31 个颜色变量:18 个通用 UI、5 个图表、8 个侧栏;另有一个根圆角变量。深色重复声明和 Tailwind 映射不重复计算。

HeroUI 的 variables.css 有 89 个不同的自定义属性声明名;shared/theme.css 有 101 个,其中 64 个是颜色映射,还有阴影、圆角、easing 等。不能将两者相加,称为 190 个独立设计决策:--color-accent 很大程度上是 --accent 接入 Tailwind 的另一个入口,很多状态又由基础值计算。

这些数字只能帮助核对文件范围。HeroUI 更广的依据是它确实给表单、状态、阴影等增加了可分别控制的角色;shadcn 的 5 个图表色也不能据此当成完整的数据可视化规范。

名称相同,语义可能不同

跨库迁移时,最容易出错的是逐字替换。

shadcn/ui 角色HeroUI 中较接近的角色注意事项
primary / primary-foregroundaccent / accent-foreground都适合主行动与主强调;需要检查实际使用位置
accent / accent-foreground根据场景使用 default、surface-hover、选中样式等shadcn accent 常用于菜单高亮、ghost hover 等,HeroUI accent 是品牌主强调,不能同名直译
muted-foregroundmuted两者都可用于弱化文字
muted按场景选择 surface 或 background 的某一层shadcn muted 常是弱化背景,HeroUI muted 是文字色;直接把它当背景会改变层次
cardsurface可作为起点;surface 的多个层级需要重新分配
popoveroverlay配对 foreground、shadow 和遮罩一起检查
destructivedangerHeroUI 另有 soft、hover 等角色
ringfocus焦点颜色之外,还要检查线宽、offset 和组件状态
input主要检查 field-border 等表单角色不能直接映射成 field-background;输入边框与背景是不同设计决策

映射表是迁移起点,不是两套体系的无损一一对应。依据分别见 shadcn Token Convention 与 HeroUI Colors。

token 怎样真正影响组件

HeroUI:基础语义、派生状态、Utility 与组件局部值

HeroUI 默认变量先定义品牌基础色及配对 foreground,再以 color-mix() 派生 hover 和 soft;共享文件将它们映射为 Tailwind 颜色入口;组件 Recipe 选择需要的角色。

例如主行动按钮可以沿以下关系追踪:

层次输入与转换结果
默认变量--accent 与 --accent-foreground定义品牌背景与其上的内容色
派生变量--accent-hover 混合 accent 与 accent foreground形成 hover 色,独立变量也允许继续覆盖
共享映射--color-accent-hover: var(--accent-hover)可通过 hover:bg-accent-hover 使用
Button Recipeprimary 变体将局部背景变量接到 accent 系列Button 获得默认、hover 等外观
按下规则Button 的局部 pressed 背景默认复用 hover,并按尺寸缩放按下反馈由颜色与形变共同表达

上游实现见 variables.css、theme.css 与 button.css。

因此,改 accent 会影响相关派生颜色与消费这些颜色的组件,但不会自动改变所有尺寸、布局或交互逻辑。当前默认体系也没有统一的全局 *-pressed 颜色家族;不能把 Button 内的局部变量泛化成所有组件都共享的契约。

shadcn:少量语义值也能表达多种状态

shadcn 的 Recipe 经常直接组合基础语义值与透明度。例如 Nova 的 destructive Badge 使用同一 destructive 色构造轻色背景、hover 背景及 focus ring。这说明缺少独立 destructive-hover 不等于没有 hover;它的变化规则保存在 Recipe 中。Nova 样式源码

取舍在修改成本:只换危险色,两种方式都方便;如果要把所有危险状态的 hover 规则从透明度变化改成特定混色,HeroUI 已有集中控制点,shadcn 项目可能需要修改相关 Recipe 或补充自己的 Semantic Token。源码由项目持有也给了 shadcn 很大的调整自由,但团队要负责约束和维护这些修改。

自动派生颜色不等于自动通过对比度验收。更换 accent、foreground、透明度或承载背景后,仍要检查真实组合;尤其 soft 背景会受其下方表面影响。无障碍要求还包括键盘、焦点、标签与状态信息,不能只看颜色。WCAG 2.2

排版、间距和动效到底算不算“有”

两者都有能力完成排版、留白、阴影与动效,区别是这些决策放在哪里。

shadcn 的核心主题清单没有把所有字号、间距、时长抽成网站级语义角色,但 Tailwind 尺度与组件 Recipe 已经在使用这些值。当前 shadcn/typeset 还提供独立的内容排版体系:body、heading、mono 字体,以及 size、leading、flow 三个主要阅读节奏控制点。它适合文档、文章、聊天内容,不能把 shadcn 概括成“没有排版体系”。

HeroUI 这两个主题文件也没有独立的 --font-*、--text-* 全套正文角色。它的主题页虽然把 typography 列入广义基础变量,但核对具体实现后,应将这里的能力归于 Tailwind 与组件 Recipe;不要据此推导出一个已经配置好的 display、heading、body、caption 产品排版规范。

间距同理。HeroUI 有根 --spacing,两者都用 Tailwind 尺度。统一修改基础单位可能影响很多尺寸,却不能保证内容密度合适。紧凑数据表、普通设置表单与大幅品牌首页往往需要不同的组合规则。

HeroUI 暴露了更多 easing、动画和延迟参数,但“展开菜单用哪条曲线”和“首页如何通过动效叙事”仍是不同层次的问题。全站动效还需要明确触发条件、节奏、可中断行为和减少动画时的替代。

一般项目够不够用

以常规组件和深浅色主题为起点,两者通常都够。 这是一项工程判断,前提是允许团队添加少量项目角色与页面规则,而不是要求每项设计决定都必须在库的默认清单中找到同名 token。

项目类型是否通常够用优先补什么
博客、文档站、知识库两者都够作为基础中文字体、正文宽度、标题节奏、代码与表格、目录和搜索路径;shadcn 可选 Typeset
企业网站、常规产品官网两者都够作为基础栅格、section 节奏、首屏重点、图片和文案;组件主题只覆盖其中一部分
常规 SaaS、设置中心、业务表单两者都够;HeroUI 默认状态与表单角色更省事业务状态、复杂验证、空状态、错误恢复、表格密度与一致的页面模板
数据分析后台都可作为基础,但需要补充图表系列、顺序与发散色阶、数据语义、密集阅读规则;shadcn 自带五色只是起点
多品牌、多租户或密度切换平台需要应用层主题与角色映射brand、mode、density 的组合规则和组件消费约束,不能只替换主色
作品集、活动页、视觉叙事网站token 足够表达很多值,成品仍高度依赖设计艺术方向、构图、图像、字体、空间和动效编排

如果已经采用 HeroUI,并且喜欢其组件视觉,不值得仅因 shadcn 有 chart 或 sidebar 命名就迁移。给项目补这两类角色通常更直接。反过来,已有 shadcn 项目只缺 success、warning,也通常可以扩展现有主题,不必更换组件库。

当几乎每个组件都需要覆盖圆角、间距、状态和阴影,才应重新评估默认 Recipe 是否符合项目。默认 token 少,不自动意味着工作多;默认变量多,也不能弥补视觉方向不匹配。

用三个真实页面验证“够用”

选一页信息展示、一页复杂表单、一页列表或数据页,使用真实中文、长标题、长数字与真实状态:

  1. 定义页面所需的角色,记录默认已有、可复用和需要新增的项目项。
  2. 同时检查深浅色;逐项看文字层级、表面、边框、焦点、hover、invalid、disabled、pending、成功与失败反馈。
  3. 把重复覆盖写进项目 Recipe 或 Semantic Token。只出现一次的装饰不必立即提升为全局契约。
  4. 改一次主强调色与基础圆角,确认预期组件响应;另改一次表单外观或图表色,确认没有误伤无关角色。
  5. 检查完整任务路径:键盘可操作,错误可理解,浮层不遮挡关键操作,长内容仍可读。

通过标准是关键页面能复用同一组规则、缺口可解释且集中、主题修改能传播到预期位置。不要凭变量数量估算“覆盖 90%”;没有项目需求清单就不存在可核查的覆盖率。

一个最小扩展例子:库负责组件颜色,项目负责页面规则

下面可加入一个已经配置 HeroUI v3 与 Tailwind v4 的 React 项目。它演示主题 token 也能服务自建 HTML,以及项目如何补充内容宽度和 section 间距;不是完整的项目脚手架。

app.css:

css
@import "tailwindcss";
@import "@heroui/styles";

:root {
  --accent: oklch(0.55 0.18 260);
  --accent-foreground: oklch(0.99 0 0);
  --radius: 0.625rem;

  /* 项目自定义的页面角色,不属于 HeroUI 默认清单。 */
  --site-content-max: 72rem;
  --site-reading-max: 68ch;
  --site-section-gap: clamp(2rem, 5vw, 5rem);
}

.dark,
[data-theme="dark"] {
  --accent: oklch(0.76 0.12 260);
  --accent-foreground: oklch(0.18 0.02 260);
}

.site-shell {
  width: min(calc(100% - 2rem), var(--site-content-max));
  margin-inline: auto;
  padding-block: var(--site-section-gap);
}

.reading-copy {
  max-width: var(--site-reading-max);
}

App.tsx:

tsx
import "./app.css";

export default function App() {
  return (
    <main className="min-h-screen bg-background text-foreground">
      <section className="site-shell">
        <div className="rounded-xl bg-surface p-6 shadow-surface">
          <h1 className="text-2xl font-semibold">项目概览</h1>
          <p className="reading-copy mt-3 text-muted">
            组件颜色来自 HeroUI,正文宽度和页面节奏由项目定义。
          </p>
          <a
            href="#details"
            className="mt-5 inline-flex rounded-lg bg-accent px-4 py-2
              text-accent-foreground hover:bg-accent-hover
              focus-visible:outline-2 focus-visible:outline-offset-2
              focus-visible:outline-focus"
          >
            阅读详情
          </a>
        </div>
        <section id="details" className="reading-copy mt-8">
          <h2 className="text-xl font-semibold">设计范围</h2>
          <p className="mt-3">内容层级、布局和交互规则仍需项目决定。</p>
        </section>
      </section>
    </main>
  );
}

在文档核验时,上述 CSS 使用 @heroui/styles 3.2.6、Tailwind 4.3.3 编译,关键 Utility 与项目规则均生成;React 示例可渲染为 HTML。将根元素切到 class="dark" 可使用深色分支。这个例子检验主题接入与样式生成,实际产品仍应按自己的文字尺寸和承载背景检查对比度。

使用 shadcn 时也可以沿用这些项目页面角色;主行动换用 primary、正文弱化色换用 muted-foreground,卡片换用 card,再按项目 Recipe 处理阴影与状态。不要将两个库的整套全局 CSS 叠在一起解决映射问题:共享变量和 Utility 名称可能冲突,若确需共存,应明确主题归属、作用域和组件适配边界。

除了 token,一个网站还要设计什么

很多设计值都能进一步 token 化;但值的选择、组合、适用条件和用户任务仍需要设计。下面这些工作对成品的影响,往往比继续增加颜色变量更直接。

设计工作需要做出的决定可检查的产物
信息架构用户来完成什么,栏目如何组织,怎样到达目标导航树、页面层级、搜索与任务路径
页面布局栅格、内容宽度、留白、首屏重点、阅读顺序首页、列表、详情、表单等真实页面模板
排版中英文字体、标题层级、正文行长、行高、长内容规则用中文长文、数字、代码和表格验证的排版样本
组件组合何时用主按钮、次按钮、Card、Dialog,哪些模式跨页面复用组件示例、variants、禁止或不建议的用法
任务与交互表单验证时机、筛选与分页、保存反馈、危险操作、撤销与恢复完整交互流程及空、加载、失败、成功状态
品牌与艺术方向图像、插画、图标、字体风格、材质和整体气质视觉参考、品牌资产及真实页面构图
内容设计标题、按钮措辞、错误说明、帮助文字、日期与数字格式文案样本与内容规则
动效编排哪些变化值得动画,注意力如何移动,如何中断和减弱转场规则、状态过渡与减少动画版本
无障碍与适配键盘路径、焦点、语义、对比度、缩放、重排与触控真实页面和关键流程的验收结果
维护与治理token 与 Recipe 的命名、责任、变更和兼容设计说明、组件目录、变更记录与必要的视觉回归

例如“正文最大宽度为 68ch”可以写成 token;但先展示结论还是先展示背景、侧栏放哪些内容、错误后如何继续,都不能靠这个数值决定。类似地,Button 的颜色和半径可以统一,但一个页面是否放了过多主按钮,仍是信息层级与交互选择问题。

一般网站建议的推进顺序

先确定用户任务与内容,再做两三张有代表性的页面,选定字体、主强调、表面层级、圆角和密度。随后统一反复出现的组件 Recipe,最后把稳定的重复决策提炼为项目 token。用真实深浅色、长内容和关键状态复验,再维护简短的使用规范。

采用 HeroUI 时,优先发挥已有的表单、状态和表面角色,补页面布局、排版与业务语义;采用 shadcn 时,复用核心主题、Tailwind 和需要的 Typeset,为重复缺失的状态补少量角色。两条路径都可以得到完整网站,决定结果的是规则能否在真实页面中成立、组件是否按规则消费,以及团队能否持续维护。

关联阅读

参考资料

博客助手

正在打开博客助手…