TL;DR
最近看到很多 APP 都有了深色模式,可以随着系统进入深色模式而进入深色模式,后来发现原来网页也可以实现这种效果,就折腾了一个下午帮这个网站弄了一个深色模式。
想要颜色跟随系统变化而变化只需要用 CSS 就可以很简单地实现。首先,需要知道在 CSS 里面有一个叫 @media 的东西,它的作用是媒体查询,也就是说可以根据设备的类型,特征和参数等来实现不同的效果。而 @media 下的 prefers-color-scheme 媒体特性可以用于判断用户系统主题色的设置。 prefers-color-scheme 下有 no-preference (无偏好); light (浅色模式); dark (深色模式)三种状态。
根据 MDN 网站的说法, no-preference 状态可以理解为:浏览器的宿主系统不支持设置主题色,或者支持主题色并默认为/被设为了未设置/无偏好。
先新建一个用来测试的网页,随便写上代码:
其中的 CSS 部分是这样的
.card{
top: 40%;
margin: auto;
box-shadow: 0px 8px 60px -10px rgba(13,28,39,0.6);
padding: 8px 10px 6px;
background: rgba(255,255,255,.596078431372549);
border-radius: 25px;
position: relative;
text-align: center;
}
p{
color: #000;
font-size: 2em;
}
.bg{
background-image: url(https://cdn.vinking.top/bg.jpg);
position: fixed;
top: 0;
left: 0;
z-index: -1;
width: 100%;
height: 100vh;
background-size: cover;
opacity: .4;
filter: blur(8px);
}然后我想将这个页面在深色模式的时候文字变成白色,后面的框变成黑色透明,背景图片换成一张暗色系并且调高一点 opacity 的话,我们使用 @media (prefers-color-scheme: dark) 配合 :root 选择器可以把 CSS 部分改成这样:
/*浅色模式*/
:root {
--p_color:#000;
--bg_img:url(https://cdn.vinking.top/bg.jpg);
--card_bg:rgba(255,255,255,.596078431372549);
--bg_op:.4;
}
/*深色模式*/
@media (prefers-color-scheme: dark){
:root {
--p_color:#fff;
--bg_img:url(https://cdn.vinking.top/iVQRxPEjsx1xw7d.jpg);
--card_bg:rgba(0,0,0,.4);
--bg_op:.9;
}
}
.card{
top: 40%;
margin: auto;
box-shadow: 0px 8px 60px -10px rgba(13,28,39,0.6);
padding: 8px 10px 6px;
background: var(--card_bg);
border-radius: 25px;
position: relative;
text-align: center;
}
p{
color: var(--p_color);
font-size: 2em;
}
.bg{
background-image: var(--bg_img);
position: fixed;
top: 0;
left: 0;
z-index: -1;
width: 100%;
height: 100vh;
background-size: cover;
opacity: var(--bg_op);
filter: blur(8px);
}这样当系统进入深色模式的时候效果就出来了
最后需要注意一下,有一些浏览器是不支持 prefers-color-scheme 的,具体支持哪一些浏览器可以在 这里 看到

