设计令牌
设计令牌(Design Tokens)是把设计决策沉淀为 CSS 变量的一套体系。插件只要消费这些变量而不是写死颜色值,就能自动获得明暗双主题、六种主题色、以及与宿主原生功能一致的视觉风格。
引入方式(一行):
import '@udhold/udhold-ui/styles/global.css'
var(--ink) 而不是 #1f2124,用 var(--line) 而不是 #ecedef——写死的颜色在暗色主题下必然出错。中性色板
中性色是设计系统的语义真相源,采用「表面四级 + 文字三级 + 线两级」的结构:
| 变量 | 亮色值 | 暗色值 | 用途 |
|---|---|---|---|
--surface | #ffffff | #232427 | 卡片、浮层等表面底色 |
--field | #f2f2f3 | #2b2c2f | 输入框、内嵌区域底色 |
--hover | #f4f5f6 | #2a2b2e | 悬停反馈底色 |
--inset | #f7f8f9 | #1f2022 | 凹陷区域(代码块底、空态图标底) |
--canvas | #f1f2f3 | #1c1d1f | 画布底(低于 surface 的一级背景) |
--ink | #1f2124 | #f2f3f4 | 主文字 |
--ink-2 | #62656b | #a5a8ad | 次级文字(说明、辅助信息) |
--ink-3 | #6c6f75 | #9a9da3 | 三级文字(占位符、禁用态) |
--line | #ecedef | #2e3033 | 分隔线 |
--line-strong | #e0e2e5 | #3a3c40 | 强分隔线、控件描边 |
另有一组历史别名(--bg-color、--card-bg、--text-color、--border-color 等)映射到上表语义色,老插件零破坏,新代码建议直接用语义名。
语义色与状态色
场景语义色(成功 / 危险 / 警示三类高频语义):
| 变量 | 亮色 | 暗色 |
|---|---|---|
--green | #189a4d | #3dbb72 |
--red | #d8353c | #f3616c |
--orange | #e56d24 | #f08a4b |
交互状态色(按钮、提示、表单校验等场景):
| 变量 | 亮色 | 暗色 |
|---|---|---|
--primary-color | #2f6fec | #4d8cf7 |
--danger-color | #d8353c | #f3616c |
--warning-color | #f59e0b | #fbbf24 |
--success-color | #189a4d | #3dbb72 |
--highlight-color | #ea580c | #fb923c |
--primary-color 不是常量:它随用户选择的主题色变化(见下节),所以主色操作永远引用它。
主题色
用户可以在宿主设置里切换六种预设主题色(蓝 / 紫 / 绿 / 橙 / 红 / 粉)或自定义颜色。实现方式是 body 上挂 theme-blue ~ theme-pink 类(自定义色则直接写内联 --primary-color),体系自动派生:
| 派生变量 | 生成规则 | 用途 |
|---|---|---|
--primary-hover | 主色压暗 15% | 主色按钮 hover |
--primary-light-bg | 主色 10% 透明度 | 选中态底色、标签底 |
--focus-ring | 0 0 0 3px 主色光圈 | 键盘焦点环 |
/* 你的组件样式 */
.tag-active {
background: var(--primary-light-bg);
color: var(--primary-color);
}
圆角、阴影与动效
| 变量 | 值 | 用途 |
|---|---|---|
--radius-sm | 6px | 小控件(标签、开关) |
--radius-md | 8px | 按钮、输入框 |
--radius-lg | 12px | 卡片、弹窗 |
--shadow-hairline | 0 0 0 1px var(--line) | 发丝线描边(比 border 更细腻) |
--shadow-raised | 亮 0 12px 30px rgba(20,26,40,.14) / 暗 rgba(0,0,0,.5) | 悬浮层投影 |
--ease-out | cubic-bezier(0.23, 1, 0.32, 1) | 标准缓动 |
--duration-fast | 120ms | 快速反馈(hover、按压) |
--duration-mid | 200ms | 常规过渡(面板、弹层) |
字体
| 场景 | 字体栈 |
|---|---|
| 正文 | Inter, -apple-system, 'Segoe UI', 'Microsoft YaHei', 'PingFang SC', sans-serif(系统栈,Windows 中文走雅黑、macOS 走苹方) |
| 代码 / 数值 | var(--font-mono) = 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, Consolas, monospace(woff2 随组件库打包,按需加载) |
正文基础排版由 global.css 设定:font-size: 14px、line-height: 1.5,插件无需重复声明。
窗口不透明度变量(勿覆盖)
Windows 下宿主支持窗口透明度(亚克力材质),体系通过这组变量传递混合率:
--window-opacity/--panel-opacity:由宿主写入;--bg-color-base:原始基色(亮#f7f7f8/ 暗#1d1e20);--bg-color:按不透明度混合后的实际背景色。
你的样式里页面底色用 var(--bg-color)、卡片用 var(--surface) 即可自动参与透明度合成。不要覆盖这几个变量,也不要在它们之上再做二次 color-mix。
用法示例
<style scoped>
.setting-row {
padding: 10px 12px;
border-radius: var(--radius-md);
color: var(--ink);
}
.setting-row:hover {
background: var(--hover);
}
.setting-row .desc {
color: var(--ink-2);
font-size: 12px;
}
</style>
配合 UnoCSS 时也可以直接写 text-[var(--ink-2)]、bg-[var(--hover)] 这类原子类。
下一节看主题与明暗模式:令牌的值是如何随宿主设置切换的,以及插件接入主题联动的三个步骤。