6

在 WEB 端实现亮/暗主题跟随系统功能

 2 years ago
source link: https://sanonz.github.io/2020/to-build-dark-and-light-theme-with-web/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

黑暗模式介绍

在 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 特性检测用户是否将系统的主题色设置为亮色或者暗色。

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

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

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

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

<!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 模式实现

body {
color: #ccc;
background-color: #1f1f1f;
}
@media (prefers-color-scheme: light) {
body {
color: #333;
background-color: #eee;
}
}

结合 CSS 变量使用

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

: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 动画是截取上边的代码运行的效果,你也可以在这里实时运行 点击运行 (如果看不到效果检查下您的浏览器是否支持)

theme.gif

JS 主题相关操作

获取当前系统主题

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

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 方法,可以利用该方法绑定事件,当主题动态改变时会触发绑定的事件,例如:

function handleChange (mediaQueryListEvent) {
if (mediaQueryListEvent.matches) {
// 用户切换到了暗色(dark)主题
} else {
// 用户切换到了亮色(light)主题
}
}

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

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

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

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

浏览器支持情况

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

browser-compat-data@2x.png

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

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

至此结束,感谢阅读。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK