跳转到内容

暗黑模式

深色不是把浅色反相。皮肤从头到尾只写语义令牌,data-theme="dark" 换掉的是语义层的取值:面往中性色阶的暗端走、品牌往亮端走、投影换成纯黑加一条浅色上沿。切主题时没有一行组件 CSS 需要改。

一条轴,七条轴

明暗只是视觉环境七条轴里的一条。它们由同一个控制器维护、投影成根元素上的一组属性,Portal 出去的浮层由 Core 桥接同一组值:

html
<html data-theme="dark" data-brand="xihan" data-density="compact" data-contrast="more" data-motion="reduce" data-transparency="reduce" dir="rtl">
取值管什么
data-themelight / dark(偏好可写 system,跟 prefers-color-scheme整套语义取值
data-brand注册过的品牌 id换整套品牌原语梯度
data-densitycomfortable / compact控件高度、内距与间隙;不缩字号和字形
dirltr / rtl逻辑属性驱动的布局镜像
data-contrastdefault / more(偏好可写 system加强边界:控件边界升到 3:1、装饰边加深、材质提高不透明度
data-motiondefault / reduce(偏好可写 system局部关闭位移与缩放动效
data-transparencydefault / reduce(偏好可写 system磨砂材质切成实体配方

主题与对比度可以分别落在不同层级:每一层采用最近的 data-themedata-contrast,子主题不撤销祖先的高对比;深色取值块里声明了 color-scheme,嵌套深色区域的原生控件也跟着走。接法见 设计令牌与主题 · 七轴视觉环境运行时

语义角色怎么翻

角色浅色深色为什么这样
--xh-bg-pageneutral 50neutral 950页面底始终比面低一档
--xh-bg-surfaceneutral 0neutral 900
--xh-bg-surface-raisedneutral 0neutral 750深色档取半档 750,与淡底差一道明度,抬起面上取淡底的部件静态时才有身形
--xh-bg-subtle-hover-active100 → 200 → 300800 → 700 → 650交互阶梯在深色档往亮端走
--xh-bg-brand-hover-activebrand 600 → 700 → 800brand 500 → 400 → 300深底上品牌往亮端走才有对比
--xh-bg-brand-subtle12% 品牌兑 surface12% 品牌兑 surface(neutral 900)兑 canvas(950)只得 L 0.202,比面还暗;兑面才比面亮一档
--xh-fg-default / -muted / -subtle / -disabled950 / 600 / 550 / 40050 / 400 / 450 / 600层级同向,比值逐条核
--xh-fg-on-brandneutral 0neutral 950深色档品牌实心底是 brand 500,白字够不着 4.5:1,改深字
--xh-border-default / -subtle / -strong200 / 100 / 300700 / 800 / 600装饰边留在 700:往下半档 750 与淡底只差 1.04,热力图格子的描边会与空格连成一片
--xh-border-control= default= default控件边界与装饰边同一条规则
--xh-ring-focusbrand 600brand 400对画布、面、淡底都 ≥ 3:1

下面这几块画的是当前主题的取值,切换文档站右上角的明暗看它们翻转:

page
surface
surface-raised
subtle
subtle-hover
subtle-active
brand
brand-subtle
default
muted
subtle
disabled
brand
subtle
default
strong
control-hover

深色档的几条特殊规则

  • 投影用纯黑,再加一条浅色上沿。 中性色阶最暗的一档比页面底还亮,拿它当投影压不出深度;四档海拔在末尾各带 1px 浅色描边把面的上沿提出来,raised / lifted 那条只画上边缘。
  • 磨砂面同样成立。 frosted 的 0.88 不透明度与 16px 模糊在深底上按黑、白、中灰、页面与品牌背景重新验过正文 4.5:1、焦点环 3:1。
  • 状态色往亮端走。 六族语气的实心底、淡底、文字与描边在深色档各有一套取值,--xh-tone-* 的槽名不变。
  • overlay 必须能从 canvas 与 surface 中辨认。 模态遮罩 --xh-bg-overlay 在两套主题下都验过与其下面的面有可见差。
  • 强制色(forced-colors)另起一套。 面改由 Canvas / CanvasText,选中改由 Highlight / HighlightText,按钮边改由 ButtonText;不靠颜色的通道(对号、指示条、chevron 转向)在这一档承担全部语义。
  • 打印取消海拔与材质效果。 纸上没有屏幕光源,投影与高光只会变成脏灰或无意义亮边:四档海拔置 none,磨砂改实体、关闭滤镜;语义角色只重映射,不动原语。

怎么接

  • 首屏由服务端直接输出七个已解析属性,客户端接管前不闪。
  • createVisualEnvironmentController 或框架的 XhConfigProvider / provideXhConfig / <xh-config> 维护状态;局部区域用带 parent 的子控制器,只覆盖自己关心的轴。
  • 自定义节点想跟着主题走,只写语义令牌与 --xh-tone-*,不写原语:原语在两套主题下是同一个值。

相关

Released under The MIT License