最近看到很多 APP 都有了深色模式,可以随着系统进入深色模式而进入深色模式,后来发现原来网页也可以实现这种效果,就折腾了一个下午帮这个网站弄了一个深色模式。
要实现颜色随系统设置自动变化,CSS 提供了一种简洁的方法。在 CSS 中,@media 规则用于进行媒体查询,它允许我们根据设备的特性和参数来应用不同的样式。而 @media 下的 prefers-color-scheme 能够检测用户系统的主题色偏好。prefers-color-scheme 支持三种值:no-preference(无偏好)、light(浅色模式)、dark(深色模式)。
Note
根据 MDN 文档的解释,no-preference 表示浏览器的宿主系统不支持主题色设置,或者支持但默认未设置或用户未指定偏好。
先创建一个测试网页:

浅色模式示例
其中的 CSS 部分是这样的
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);
}
在深色模式下,我们想要将文字颜色改为白色,背景框设为黑色透明,同时更换背景图片为暗色系,并适提高其透明度。为了实现这些样式的变化,可以使用 @media (prefers-color-scheme: dark) 媒体查询,结合 :root 伪类选择器,将 CSS 代码修改如下:
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);
}
当用户切换到系统的深色模式时,页面的效果也会自动更新。

深色模式示例
Note
最后需要注意一下,有一些浏览器是不支持 prefers-color-scheme 的,具体支持哪一些浏览器可以在 这里 看到