应使用 :root 定义原子色变量(如 --color-primary),统一管理十六进制/rgb/hsl 值,禁用命名色和复合样式;支持运行时修改、暗色模式及 JS 动态更新,fallback 必须为其他原子色变量,工具类仅限语义明确的四类。

用 :root 定义原子色变量,别在组件里硬写十六进制
设计规范里的主色、中性灰、状态色(如 --color-success)必须统一管理,否则改一个蓝色要搜遍所有 color: #2563eb。把颜色全塞进 :root 是最轻量、最易维护的方式。
常见错误:在 .button 里直接写 background: #3b82f6,结果设计稿把品牌蓝从 #3b82f6 调成 #2563eb,你得手动改 17 个文件。
- 所有原子色变量名用
--color-xxx前缀,比如--color-primary、--color-gray-200 - 值必须是十六进制、rgb() 或 hsl(),避免用命名色(
blue、lightgray),它们在不同浏览器渲染不一致 - 不要在
:root里定义复合样式(如--button-bg),那属于组件层逻辑,会污染原子色体系
:root {
--color-primary: #2563eb;
--color-gray-100: #f9fafb;
--color-gray-500: #6b7280;
--color-error: #ef4444;
}
为什么不用 CSS 自定义属性以外的方式(比如 Sass 变量)
如果项目已用 Sass/Less,容易下意识继续用 $primary-color。但纯 CSS 的 :root 变量有不可替代的优势:运行时可变、支持 JS 动态修改、无需构建步骤、兼容现代所有浏览器(Chrome 49+ / Firefox 31+ / Safari 9.1+)。
常见错误:用 Sass 变量生成一整套 .text-primary 类,结果夜间模式切换时无法动态更新——Sass 是编译时处理,生成的 CSS 固定死了。
立即学习“前端免费学习笔记(深入)”;
- JS 改色只需一行:
document.documentElement.style.setProperty('--color-primary', '#1d4ed8') - 媒体查询里也能用:
@media (prefers-color-scheme: dark) { :root { --color-gray-100: #111827; } } - Sass 变量无法被 CSS-in-JS 库(如 Emotion)或 Web Components 内部读取,而
:root变量全局可见
var(--color-xxx) 的 fallback 机制怎么用才安全
直接写 color: var(--color-text); 很危险——万一变量没定义,浏览器会按默认值(通常是黑色)渲染,可能造成文字不可读。fallback 不是可选项,是必填项。
常见错误:写成 var(--color-text, #374151),但这个 fallback 值本身又是一个魔法数字,违背了原子色初衷。
- fallback 必须是另一个已定义的原子色变量,例如
var(--color-text, var(--color-gray-700)) - 不要 fallback 到
inherit或transparent,除非你明确知道父元素行为 - 在深色模式下,
var(--color-bg, #ffffff)这种写法会让浅色 fallback 在暗背景下“消失”,应改为var(--color-bg, var(--color-gray-50))并确保--color-gray-50在暗色模式下也合理
原子色类(如 .text-primary)该不该生成?怎么生成才不冗余
生成工具类本身没问题,但必须严格限定范围:只生成语义明确、高频使用的组合(文字色、背景色、边框色),且每个类只干一件事。别搞出 .bg-primary-hover 或 .text-primary-bold 这种混合职责的类。
常见错误:用 PostCSS 插件把所有原子色自动转成 200 个工具类,结果 .text-gray-900 在项目里一次都没用过,白占体积。
- 只生成四类:文本色(
.text-xxx)、背景色(.bg-xxx)、边框色(.border-xxx)、描边色(.stroke-xxx) - 类名中的色值必须和
:root变量名一一对应,比如.text-primary对应--color-primary,不映射到具体数值 - 用
@apply(Tailwind)或composes(CSS Modules)替代重复写var(),但前提是构建工具支持;否则宁可手写color: var(--color-primary)
:root 直接写死颜色值,整个体系就漏气了。上线前用正则 /#[0-9a-fA-F]{3,6}/g 扫一遍源码,比写十个文档都管用。









