让你的网站自动切换深色主题
| 没有评论
随着深色模式越来越流行,微信、知乎、各种操作系统等等都提供了深色主题。细心的朋友也许会发现,很多网站都已经可以根据用户当前的系统主题自动使用对应配色了,甚至当用户切换系统主题的同时,这些网站也能同步切换。
2019年7月30日,Chrome 发布了 76 版本,标志着 prefers-color-scheme
被大部分的现代浏览器所支持。
prefers-color-scheme
是一种媒体特征(Media Feature),在媒体查询(Media Query)中使用,用于检测用户是否有要求浏览器使用浅色(light)或者深色(dark)模式。
该特征只有 2 种可能的值:dark
和 light
。
因此,我们可以这样设置颜色:
/* 深色模式 */
@media (prefers-color-scheme: dark) {
body {
background-color: black;
}
}
/* 浅色模式 */
@media (prefers-color-scheme: light) {
body {
background-color: white;
}
}
这样设置会导致网站主题随着用户系统主题的改变而改变,如果使用场景需要允许用户自定义主题,那么单用 CSS 来控制就不够了,还需要配合 Javascript。
那么 js 如何获取媒体查询的结果呢?
在 window 对象中有这样一个方法:matchMedia
,几乎所有浏览都支持它,可以放心的使用。这个方法只接受一个参数,就是媒体查询的字符串,并返回一个 MediaQueryList
对象实例。该对象有只有 3 个属性:
- media:媒体查询,等于传入的参数。
- matches:布尔值,表示查询结果正确与否。
- onchange:null,允许开发者传入一个回调函数,当媒体查询的结果改变时就会被触发。
// 本例通过设置 body 的 classname 来控制主题颜色
const mql = window.matchMedia('(prefers-color-scheme: dark)');
if (mql.matches) {
// 当前为深色模式
document.body.classList.add('dark-mode');
} else {
// 当前为浅色模式
document.body.classList.remove('dark-mode');
}
如果需要可以根据系统主题的改变而自动切换模式的功能,那么就可以设置 onchange 事件的回调函数,当媒体查询结果改变时,回调函数就会被触发,可以在函数内部进行主题切换。
// 当设置要根据系统主题自动切换模式,执行以下代码
const mql = window.matchMedia('(prefers-color-scheme: dark)');
// 设置 onchange 事件的回调函数
mql.onchange = function (evt) {
if (evt.matches) {
// 当前为深色模式
document.body.parentElement.classList.add('dark-mode');
} else {
// 当前为浅色模式
document.body.parentElement.classList.remove('dark-mode');
}
}
再配合一键全站切换深色模式的魔法代码,即可快速实现根据系统主题选择用浅色还是深色模式的功能。
/* 魔法代码:一键全站切换深色模式 */
html.dark-mode {
filter: invert(1) hue-rotate(180deg);
}
(完)