深色模式应避免纯黑背景,推荐使用深灰色如#121212;宜用hsl()通过调节lightness值实现明暗适配,并结合CSS自定义属性与prefers-color-scheme媒体查询统一管理主题色,同时确保文本对比度≥4.5:1。

深色模式下直接用 #000000 或 black 通常不是好选择
纯黑背景(#000000)在 OLED 屏幕上会触发全像素关闭,造成视觉“发灰”或文字边缘发虚;同时与浅色模式的白底(#FFFFFF)对比度过高,易引发视觉疲劳。实际项目中更推荐用「深灰」而非纯黑,例如 #121212(Material Design 深色基准)或 #1e1e1e(VS Code 暗色主题)。这类颜色保留了轻微亮度,更适合长时间阅读。
用 hsl() 动态调低亮度(l)实现深色适配
HSL 的 l(lightness)参数直观对应明暗程度,范围是 0%(黑)到 100%(白),中间 50% 是纯灰。比起硬编码十六进制,用 hsl(h, s, l) 可以从浅色主色一键推导出协调的深色变体——只需降低 l 值,保持 h(色相)和 s(饱和度)不变。
常见做法:
- 浅色模式主色:
hsl(210, 100%, 60%)(一种明亮蓝) - 对应深色模式背景:
hsl(210, 100%, 12%)(同色相,仅压低亮度) - 对应深色模式文字:
hsl(210, 100%, 92%)(提高亮度,确保可读性)
注意:不是所有浏览器都支持 CSS 中的 hsl() 动态计算,所以需手动设定值,不能写成 hsl(210, 100%, calc(60% - 48%))。
立即学习“前端免费学习笔记(深入)”;
配合 @media (prefers-color-scheme: dark) 切换 HSL 值
现代方案依赖媒体查询接管系统偏好,但关键在于——不要为每个颜色单独写一遍规则,而是用 CSS 自定义属性统一管理:
:root {
--text-primary: hsl(210, 100%, 12%);
--bg-primary: hsl(210, 100%, 92%);
}
@media (prefers-color-scheme: dark) {
:root {
--text-primary: hsl(210, 100%, 92%);
--bg-primary: hsl(210, 100%, 12%);
}
}
body {
color: var(--text-primary);
background-color: var(--bg-primary);
}
这样改一处 --text-primary 就全局生效,且语义清晰。如果项目用 Sass/Less,也可封装 darken-hsl($h, $s, $l, $amount) 函数批量生成,但纯 CSS 场景下仍推荐手调 l 值并验证实际显示效果。
亮度调整不是线性缩放,要实测对比度是否达标
WCAG 2.1 要求正常文本对比度 ≥ 4.5:1。比如浅色模式下 hsl(0, 0%, 20%) 文字配 hsl(0, 0%, 98%) 背景,对比度约 12:1;但换成深色模式后,若把文字设为 hsl(0, 0%, 80%)、背景设为 hsl(0, 0%, 15%),对比度可能只有 3.8:1 —— 看似更亮,实则不达标。
建议:
- 用浏览器 DevTools 的颜色拾取器查看渲染后的 RGB 值,再用在线工具(如 WebAIM Contrast Checker)验证
- 避免将
l值设为 0% 或 100%,留出余量应对不同屏幕 Gamma 表现 - OLED 设备上,
l值低于 5% 的区域容易出现色彩断层,慎用hsl(0, 0%, 2%)类极端值
深色模式的颜色不是“浅色取反”,而是重新平衡亮度层级;HSL 提供了最可控的调节维度,但最终得靠人眼在真实设备上确认是否舒服。










