HSL 管理深色模式颜色的核心是固定色相(Hue),独立调节亮度(L)和饱和度(S):背景层 L≈10%–20%,卡片 L≈25%–35%,主文本 L≈90%–95%,并降低 S 值防辉光,配合 prefers-color-scheme 用 CSS 变量实现平滑切换。

用 HSL 而不是 RGB 或十六进制来管理深色模式颜色,核心在于:亮度(Lightness)和饱和度(Saturation)可独立调节,同一色相(Hue)下能快速生成协调的明暗层级与柔和度变化,避免手动试错或颜色断裂。
用 HSL 定义基础色相,固定 hue 值
选一个主色(比如蓝色),先确定它的 hue(如 210),之后所有衍生色都保持这个值不变。这样从浅灰蓝到深靛蓝,视觉上始终是“同一种蓝”,不会偏紫或偏绿。CSS 中可定义为 CSS 自定义属性:
:root {
--brand-h: 210;
--brand-s: 70%;
--brand-l-light: 85%;
--brand-l-dark: 25%;
}按场景分层控制亮度(L),而非硬编码颜色
深色模式不是简单“把背景变黑”,而是构建有纵深的明暗系统。建议按功能划分 L 值范围:
-
背景层:L ≈ 10%–20%(如
hsl(210 15% 15%)),保留轻微灰度,避免纯黑刺眼 - 卡片/容器:L ≈ 25%–35%,比背景亮但低于文字,形成自然浮起感
- 主文本:L ≈ 90%–95%,确保对比度 ≥ 4.5:1(可用 WebAIM 对比检查器 验证)
- 次要文本:L ≈ 60%–70%,降低注意力干扰,不牺牲可读性
动态调整饱和度(S)适配深色环境
同样 hue 和 lightness 下,高饱和色在深底上容易“发光”或产生边缘辉光(尤其蓝、青、品红)。深色模式中适当降低 S 值更稳重:
立即学习“前端免费学习笔记(深入)”;
- 品牌色用于按钮时:S 从 70% → 50%(更内敛,不抢界面)
- 状态色(如 success / warning):S 控制在 40%–60%,避免深背景下过度刺激
- 悬停态可微增 S(+5%–10%)和 L(+3%–5%),比单纯变亮更自然
配合 prefers-color-scheme 实现平滑切换
不要用 JS 切换整套 class,优先用媒体查询 + CSS 变量继承:
@media (prefers-color-scheme: dark) {
:root {
--bg: hsl(var(--brand-h) var(--brand-s) 15%);
--card: hsl(var(--brand-h) calc(var(--brand-s) * 0.7) 28%);
--text-primary: hsl(0 0% 94%); /* 中性白,非纯白 */
}
}这样 hue/s/l 全局可控,动画过渡也更顺滑(可对 background、color 等属性加 transition)。










