跳到正文

颜色

raft-ui 的颜色分三层。组件从不直接写某个颜色值:它只说自己要什么用途的颜色,比如“主按钮的填充色”或“错误文字”,具体是哪个颜色由主题决定。

层命名存什么
色板--r-palette-{hue}-{1..12}Raft 品牌色相的 12 级色阶
别名--rw-alias-{property}-{state}-{role}颜色的用途;指向色板里的某一级
组件--rl-{component}-*组件自己的插槽;只读别名

色板

每个色相有 12 级,每一级在所有色相里的用途都相同,第 9 级就是品牌色本身。亮色色阶由 Brutal 和 Elegant light 共用;Elegant dark 换成暗色色阶,每一级的用途不变,所以所有别名都会自动跟着模式走。切换页面顶部的主题就能看到。

123456789101112contrastgrayyellowpinkcyanlimeorangered

contrast 是第 9 级实心填充上的文字颜色:同色系的深色,不用纯黑。

每一级用来做什么

参照 Radix Colors。

级用途别名
1–2页面底色、次级区域底色bg-page、bg-panel(中性色)
3 / 4 / 5组件底色:常态、悬停、按下surface、surface-hover、surface-pressed
6 / 7 / 8边框:弱、常态、悬停border-subtle、border、border-hover
9 / 10实心填充:常态、悬停fill、fill-hover
11白底或 1–5 级底上的彩色文字text
12同色系的高对比文字text-strong
contrast实心填充上的文字text-on-fill

两条规则保证文字可读:

  • 彩色底上的字用同一色系的深色。 黄色底配深橄榄棕,青色底配深青色。彩色底上用纯黑或灰色文字会显得脏。
  • 浅色底上的彩色字用第 11 级。 它是在 1–5 级底上仍能达到 WCAG AA(4.5:1)的最鲜艳的一级。

别名

命名遵循 how-to-style:先写属性,再写状态,角色放最后。组件映射不同类型时只需要改最后一段。

css
.r-button { &&--error-type { --rl-button-family-fill: var(--rw-alias-fill-error); --rl-button-family-fill-hover: var(--rw-alias-fill-hover-error); --rl-button-family-text: var(--rw-alias-text-error); } }

各个角色和它们使用的色相:

surface3surface-hover4surface-pressed5border-subtle6border7border-hover8fill9fill-hover10text11text-strong12text-on-fillcontrast
neutralgray
primaryyellow
accentpink
infocyan
successlime
warningorange
errorred

中性的文字和底色有自己的名字:--rw-alias-bg-page、--rw-alias-bg-panel、--rw-alias-bg-raised(浮在凹陷底色之上的东西,比如分段控制器选中的那一段:浅色模式是白色,深色模式比底色更亮)、--rw-alias-label-primary / -secondary / -tertiary / -disabled、--rw-alias-border-strong(Brutal 的墨色)和 --rw-alias-border-focus。--rw-static-white 和 --rw-static-black 永远不变。

反馈色

状态(info、success、warning、error)在所有组件上都要是同一种说法,所以组件不自己挑颜色,而是读 --rw-feedback-{property}-{role},由每个主题统一决定一次。

状态色单独成一组,不借用上面各角色的品牌色相。错误是 15° 的覆盆子红,警告是 72° 的琥珀色,成功是 153° 的真绿,三者容易分清,也不挤在品牌的暖色带里。只有错误是饱和的;警告和成功收着一些。输入框用中间调;文字用同一色相更深的一级,保证满足 AA 对比度(4.5:1)。深色模式有一组单独调亮的值,一个颜色两处都用。

TokenElegant(浅色和深色)Brutal
--rw-feedback-text-{role}状态色,浅色模式下加深到满足 AA;用于提示文字和图标同左
--rw-feedback-border-{role}状态色状态色,替换墨色描边
--rw-feedback-shadow-{role}无状态色的硬阴影

处于某个状态的输入框整体换成同一个颜色:Elegant 的细线变成状态色,Brutal 的描边和硬阴影一起变成状态色。切换页面顶部的主题对比看。

info
Synced 2 minutes ago
success
Looks good
warning
Double-check this
error
Not a valid email

Input 和 Select 的 status 都读这层 token,之后的表单类组件和提示信息也一样。

对比度

按当前主题实时计算。组件用到的每一对颜色都应该达到 4.5:1。

pairneutralprimaryaccentinfosuccesswarningerror
11 on panelAa—Aa—Aa—Aa—Aa—Aa—Aa—
11 on 3Aa—Aa—Aa—Aa—Aa—Aa—Aa—
11 on 5Aa—Aa—Aa—Aa—Aa—Aa—Aa—
contrast on 9Aa—Aa—Aa—Aa—Aa—Aa—Aa—
contrast on 10Aa—Aa—Aa—Aa—Aa—Aa—Aa—

修改颜色

覆盖色板里的一级,所有指向它的别名都会跟着变,可以作用于整个页面,也可以只在某个 ConfigProvider 里:

tsx
<ConfigProvider themeOverrides={{ "--r-palette-yellow-9": "oklch(0.86 0.17 85)" }}>…</ConfigProvider>

覆盖某个别名,只改变这一个用途用的颜色,不动色板:

tsx
<ConfigProvider themeOverrides={{ "--rw-alias-fill-primary": "var(--r-palette-orange-9)" }}>…</ConfigProvider>