关于 theme-colors
面向 UI 开发的配色规范技能,要求组件通过主题角色引用颜色,而不是散布硬编码色值。它说明了角色定义、透明度处理、例外情形及扫描代码库的审计步骤。
主要功能
- 01通过主题角色统一取色
- 02用 alpha() 处理透明度
- 03将渐变绑定到主题值
- 04审计并替换硬编码颜色
- 05明确允许色值字面量的例外
适用场景
- 01清理组件中的硬编码颜色
- 02构建支持深色模式的配色
- 03审查渐变和透明叠加样式
- 04为品牌或数据可视化扩展主题色
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ saschb2b/ skills --skill theme-colors安装后在 Claude Code 中输入/theme-colors确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CARD.manifest.jsonCARD.mdCARD.md.sigstoreCARD.svgpermissions.yaml详细介绍
主题颜色
规则
所有颜色都来自主题。不要使用十六进制字面值、rgba() 字符串或零散的颜色值。
主题在一个地方一次性按角色定义颜色(primary、secondary、error、surface、text)。组件引用角色,而不是颜色值。更改品牌色只需更新一个文件。深色模式使用相同的主题,只是颜色值不同。组件通过 alpha() 辅助函数,根据角色颜色生成自己的悬停、聚焦和按下状态透明度。
LLM 生成 UI 时最常见的问题,是在组件文件中到处散落十六进制代码(color: "#3B82F6"、bgcolor: "#1E293B"、background: "rgba(255,255,255,0.5)")。训练语料以硬编码颜色的教程代码为主,因此默认生成结果往往不理想。
词汇表:10 个角色
| 角色 | 含义 | 用途 |
|---|---|---|
primary | 主要品牌色 | 主按钮、活动标签页、重点突出内容 |
secondary | 互补强调色 | 开关、FAB、选择控件 |
error | 错误或具有破坏性的操作 | 错误消息、删除按钮 |
warning | 警示,但尚未构成错误 | 警告横幅、高风险操作确认 |
info | 中性信息,无紧迫性 | 工具提示、信息徽标、帮助文本 |
success | 正面结果 | 成功通知、完成状态 |
background.default | 页面背景(“桌面”) | 应用的基础背景 |
background.paper | 凸起的表面(“桌面上的纸张”) | 卡片、对话框、下拉菜单、菜单、抽屉 |
text.primary | 主要文本,强调度高 | 标题、正文 |
text.secondary | 弱化显示的文本 | 说明文字、时间戳、辅助文本 |
每个角色都会自动派生 .light、.dark 和 .contrastText。使用默认值;只有在有明确的对比度或设计原因时才覆盖。
编写 UI 时的默认做法
这样做:
<Box sx={{ color: "text.primary", bgcolor: "background.paper" }}>
<Button color="primary">Save</Button>
</Box>
不要这样做:
<Box sx={{ color: "#1E293B", bgcolor: "#FFFFFF" }}>
<Button sx={{ bgcolor: "#3B82F6" }}>Save</Button>
</Box>
设置透明度时,请针对主题颜色使用 alpha(),不要使用字面量 rgba():
import { alpha } from "@mui/material";
sx={(theme) => ({
bgcolor: alpha(theme.palette.secondary.main, 0.08),
})}
对于渐变以及其他需要使用主题值的字符串类型 CSS,请使用 sx 回调形式,以便访问主题:
sx={(theme) => ({
background: `linear-gradient(135deg, ${theme.palette.primary.main} 0%, ${theme.palette.accent.alt} 100%)`,
})}
适合使用十六进制字面值的三个地方
- 主题定义本身(
createTheme({ palette: { primary: { main: "#6366F1" } } }))。主题文件是存放十六进制值的地方,这是有意为之。 - 不适合标准角色的自定义调色板扩展:品牌专属强调色、具有语义的可视化调色板(例如金融领域中表示上涨的绿色/表示下跌的红色)。将它们作为命名条目添加到主题中,然后在组件中按名称引用。
- 内联 SVG 片段,其中颜色属于外部资源(徽标、非图标库中的图标)。将字面值保留在资源本身中,不要在其他组件中重复散布相同的十六进制值。
其他所有颜色都应使用主题令牌。
审查工作流
- 使用 grep 搜索代码库中的颜色字面值:
grep -rEn '(#[0-9a-fA-F]{3,8}|rgba?\(|hsla?\(|oklch\()' src/ app/ components/ - 对每个匹配项进行分类。
- 如果位于主题文件或 SVG 属性中,则保留。
- 其他位置都应转换为主题令牌。
- 对于
rgba(R, G, B, A),找出其 RGB 值近似对应的角色,并替换为alpha(theme.palette.<role>.<variant>, A)。必要时使用sx回调。 - 对于包含字面值色标的渐变,将其移入
sx={(theme) => ...}回调,并插入theme.palette.<role>.<variant>。 - 对于内联使用的命名颜色(
color: "blue"、bg: "white"),替换为最接近的主题角色。 - 对于主题中没有的“魔法”颜色,不要添加内联覆盖。应将其映射到最接近的现有角色,或将其作为命名条目添加到主题中,并从组件中引用该条目。
经验法则
- 主题颜色必须是不透明的。透明度应通过组件中的
alpha()实现,而不是在调色板定义中设置。预先稀释的主题颜色会与悬停、聚焦和按下状态的叠加效果层层累积,导致显示异常。 - 除非遇到具体的对比度或设计问题,否则不要手动覆盖
.light/.dark/.contrastText。默认值是根据感知对比度推导得出的。 - 这 10 种角色足以满足大多数应用的需求。添加包含 30 种角色的调色板,会让主题变回一张需要额外操作的十六进制颜色值表格。
来源
评论
支持 Markdown