在白天设计深色模式

一种基于对比度、层级、系统偏好、动效、媒体表现和真实环境验证的深色模式检查方法。

发布于
2026年2月19日
更新于
2026年8月2日
阅读进度
2 分钟
标签
design, accessibility, web, testing
Read the English version

黑暗不是目标

深色模式真正成功,是在整体亮度变化后,信息层级和阅读舒适度仍然成立。把白色换成黑色,再机械地反转其他颜色,通常只会得到刺眼文字、浑浊边框,以及比正文更抢眼的强调色。 用于视觉测试的灰阶对比度占位图

应当先定义语义 token,而不是为每个组件单独指定颜色。Token 描述的是职责,因此数值变化时,不需要重写组件的表达方式。

:root {
  color-scheme: light dark;
  --surface: #f6f4ef;
  --surface-raised: #ffffff;
  --text: #1b1b19;
  --muted: #68675f;
  --border: #d8d5cc;
  --accent: #315ea8;
}

@media (prefers-color-scheme: dark) {
  :root {
    --surface: #151513;
    --surface-raised: #1e1e1b;
    --text: #f2f0e8;
    --muted: #aaa79d;
    --border: #393832;
    --accent: #8bb8ff;
  }
}

不要让每一个抬高表面都按相同比例变亮。层级、分组和强调也可以通过间距与边框表达。如果每张卡片都在深色页面上发光,整个界面会迅速变得嘈杂。

不要只检查色板

场景 检查重点 常见失败
长文章 阅读舒适度与链接可见性 纯白文字产生眩光
代码块 语法对比度与横向溢出 弱化 token 完全消失
禁用控件 状态是否仍可辨认 看起来仍可操作
外部图片 图片边缘处理 明亮图片支配整个页面
焦点状态 键盘当前位置是否明确 轮廓与边框融在一起
错误状态 离开颜色后仍能表达含义 只有红色这一种信号
  • 降低屏幕亮度后文字仍可阅读。
  • 链接不只依赖颜色表达。
  • 边框可见,但不会像发光一样突出。
  • 原生控件遵循 color-scheme
  • 页面跳转和刷新后仍保存主题选择。
  • 焦点与错误状态保持明确。
  • 桌面和移动端截图都经过检查。
  • 动效遵循 reduced-motion 偏好。

测试切换与例外

主题切换可能暴露许多平时看不到的问题:样式加载前的闪烁、仍使用旧颜色的浏览器控件,或者已经按上一套色板渲染的图表。需要测试首次访问、硬刷新、后退导航,以及页面打开时系统主题突然变化。

是否应该自动压暗所有图片?

不应该。自动压暗会改变作品本身,也可能让照片失真。更稳妥的方法是使用轻微边框或周围表面来控制视觉关系,只对自己掌控的装饰资产做特殊处理。如果图片是论述的重要部分,应当保留它原本的明暗。

好的深色模式并不是另一套视觉身份,而是用不同的光线预算表达同一个信息层级。

Bojin Li

写软件、系统,以及那些还没定型的部分。