黑暗模式介绍

在 2018~2019 年两年时间中,桌面端系统 Windows、MacOS 和 移动端系统 Android、iPhone 分别推出了 黑暗模式。在之前不管是微软的 Windows,还是苹果的 MacOS,界面都是以亮色为主,在夜间为了防止刺眼,我门通常会把屏幕亮度调暗,虽然调暗会有所改善,但是依然避免不了有点刺眼。有个别 APP 也提供的有黑暗模式,这种功能通常要在设置里手动打开,打开后白天 APP 依然是黑暗模式,虽然个别 APP 提供的有根据时间区间来控制开关黑暗模式,但是每个支持的 APP 都要设置一遍很麻烦,况且大多还不支持根据时间调节功能,即使都设置好了,返回到系统主页的时候,系统层面还会是刺眼的亮色。而目前系统提供的黑暗模式则可以让 APP 端跟随系统,这样就保证了不管是进系统界面还是进入 APP 页面都会保持统一的亮/暗色模式。

这里分别引用苹果与谷歌的介绍

苹果介绍:这是一种戏剧性的新外观,可以帮助您专注于工作,以及营造一种无干扰的环境。

谷歌介绍:

  1. 可大幅度减少耗电量(取决于设备屏幕,例如 OLED 屏幕)。
  2. 为弱视以及对强光敏感的用户提高可视性。
  3. 让所有人都可以在光线较暗的环境中更轻松地使用设备。

各个平台对黑暗模式支持的时间

系统支持

  • 苹果的 MacOS 在 2018 年 09 月推送了一个版本为 Mojave 10.14 的更新,其中加入了黑暗模式
  • 微软的 Win10 在 2018 年 10 月推送了一个版本为 1809 的更新,其中加入了黑暗模式
  • 谷歌的 Android 在 2019 年 09 月发布了 Android Q,其中加入了黑暗模式
  • IOS 13 在 2019 年 09 月推送,其中加入了黑暗模式

软件支持

  • 苹果版微信则在 2020 年 03 月 22 日推送了版本为 7.0.12,其中加入了黑暗模式
  • 安卓版微信则在 2020 年 03 月 22 日推送了版本为 7.0.12,其中加入了黑暗模式

从上边时间点可以看出:系统方面目前各大系统都已经支持 黑暗模式 了;软件适配方面,目前只有少部分软件做了黑暗模式适配。在 2018~2019 两年各大系统做了适配支持,可以预测在 2020~2021 两年主流 APP 将会适配黑暗模式。

CSS 实现主题跟随系统自动切换

语法规则

利用媒体查询的 prefers-color-scheme 特性检测用户是否将系统的主题色设置为亮色或者暗色。

1
2
3
@media (prefers-color-scheme: {mode}) {
/* CSS Rules */
}

其中 mode 可选值为:dark、light、no-preference。

  • dark 匹配系统暗色主题
  • light 匹配系统亮色主题
  • no-preference 系统未得知用户在这方面的选项

例子

例如以下例子展示了当系统主题为 暗色(dark) 时,覆盖 body 样式的字体色与背景色。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body {
color: #333;
background-color: #eee;
}
@media (prefers-color-scheme: dark) {
body {
color: #ccc;
background-color: #1f1f1f;
}
}
</style>
</head>
<body>
Hello Theme!
</body>
</html>

同理以上效果也可以用 light 模式实现

1
2
3
4
5
6
7
8
9
10
body {
color: #ccc;
background-color: #1f1f1f;
}
@media (prefers-color-scheme: light) {
body {
color: #333;
background-color: #eee;
}
}

结合 CSS 变量使用

首先在 :root 下定义亮色主题配色变量,然后利用主题媒体查询特性,判断当系统为暗色主题时覆盖 :root 下为亮色主题配色的变量。在需要使用变量的地方调用 var() 来引用变量值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
:root {
--color: #333;
--bg-color: #eee;
}
@media (prefers-color-scheme: dark) {
:root {
--color: #ccc;
--bg-color: #1f1f1f;
}
}

body {
color: var(--color);
background-color: var(--bg-color);
}

效果展示

这个 gif 动画是截取上边的代码运行的效果,你也可以在这里实时运行 点击运行 (如果看不到效果检查下您的浏览器是否支持)

JS 主题相关操作

获取当前系统主题

利用 matchMedia(mediaQueryString) 媒体查询方法,检测当前主题状态,返回一个新的 MediaQueryList 对象,表示指定的媒体查询字符串解析后的结果。

1
2
3
4
5
6
7
8
9
const mediaQueryListDark = window.matchMedia('(prefers-color-scheme: dark)');
if (mediaQueryListDark.matches) {
// 系统当前是暗色(dark)主题
}

const mediaQueryListLight = window.matchMedia('(prefers-color-scheme: light)');
if (mediaQueryListLight.matches) {
// 系统当前是亮色(light)主题
}

监控系统主题变动

利用媒体查询可以获取 MediaQueryList 对象,该对象有 addListener 方法,可以利用该方法绑定事件,当主题动态改变时会触发绑定的事件,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function handleChange (mediaQueryListEvent) {
if (mediaQueryListEvent.matches) {
// 用户切换到了暗色(dark)主题
} else {
// 用户切换到了亮色(light)主题
}
}

const mediaQueryListDark = window.matchMedia('(prefers-color-scheme: dark)');

// 添加主题变动监控事件
mediaQueryListDark.addListener(handleChange);

// 移除主题变动监控事件
mediaQueryListDark.removeListener(handleChange);

测试地址 点击运行,先打开控制台版面,在自己的设备系统设置里来回切换系统主题,然后去控制台查看打印的日志。

浏览器支持情况

我们在进行开发的时候先写一套默认主题色,然后用媒体查询去覆盖默认主题色,这样做不具有破坏性,当浏览器不支持时就会使用默认色,支持时会根据系统当前主题显示对应的配色。

小结

站点增加亮/暗主题配色,能有效防止用户在烈日下看不清暗主题,以及在夜间看亮主题太刺眼的问题,可以极大的提升用户浏览体验,建议大家给自己的站点增加亮/暗主题跟随系统功能。

本博客站点也增加了暗色主题,您也可以直接用本站点来测试。

至此结束,感谢阅读。