
什么是CSS颜色分层,不是简单写几个--color-primary
颜色分层本质是把颜色按语义+使用场景切开,而不是按色值归类。比如--color-primary不能只代表“蓝色”,它得明确回答:这个蓝用在按钮上?还是标题文字?还是禁用态背景?同一色相在不同语境下亮度、对比度、透明度都该不同。很多人直接定义--blue-500然后到处用,结果在深色模式下文字看不见,或在按钮上和背景对比不足——问题不在变量名,而在没分层。
必须拆开的三层:基础色、语义色、场景色
基础色只存原始色值(如#2563eb),不带任何用途暗示;语义色绑定意图(--color-primary、--color-success);场景色锁定具体用途(--color-button-primary-bg、--color-text-heading)。这三层不能合并,否则换主题时要全局搜替换,且无法单独调整某处对比度。
- 基础色只在
:root里定义一次,不直接用于样式 - 语义色通过
calc()或color-mix()从基础色派生,加灰度/透明度适配可访问性 - 场景色必须包含明确上下文,比如
--color-form-input-border-hover比--color-border-hover更安全——后者可能被误用在卡片边框上
深色模式下color-scheme和@media (prefers-color-scheme)怎么选
color-scheme: light dark只是告诉浏览器你支持什么模式,不自动切换颜色;真正在变的是@media (prefers-color-scheme: dark)块里的变量重定义。常见错误是只在:root里写一遍变量,然后指望color-scheme自动翻转——它不会。
- 所有场景色变量都要在
@media块里重新赋值,不能只改基础色 - 别用
hsl()动态算深色值,浏览器对hsl()在深色模式下的渲染不一致,老老实实用两套rgb()或十六进制 - 测试时关掉系统“减少动画”和“增加对比度”设置,它们会干扰
prefers-color-scheme的触发
对比度不够时,别硬调opacity,用color-mix()或oklch()
opacity: 0.6会让整个元素变淡,包括子元素和阴影,破坏设计一致性。WCAG要求文本与背景对比度至少4.5:1,但很多团队用rgba(0,0,0,0.7)应付,结果在浅灰背景上依然不达标。
立即学习“前端免费学习笔记(深入)”;
-
color-mix(in srgb, black 70%, white 30%)能精准控制灰度,且不影响其他属性 - 如果目标浏览器支持,
oklch(0.5 0.1 240)比hsl()更符合人眼感知,调亮暗更自然 - 用
contrast()函数做兜底(如filter: contrast(1.2))是最后手段——它影响渲染性能,且不可预测
真正难的不是定义变量,而是守住分层边界:设计师改一个--color-primary,前端得立刻知道哪些场景色会连锁变化,哪些必须手动微调。没人检查的var(--color-text-secondary)最容易悄悄变成#888,在深色模式下直接糊成一片。










