129 lines
4.1 KiB
Markdown
129 lines
4.1 KiB
Markdown
---
|
||
title: 如何根据系统主题自动响应CSS深色模式
|
||
date: 2020-03-31 14:06:26
|
||
permalink: /pages/5dde351274f1e39d
|
||
sticky: 1
|
||
categories:
|
||
- 页面
|
||
- CSS
|
||
tags:
|
||
- css
|
||
author:
|
||
name: xugaoyi
|
||
link: https://github.com/xugaoyi
|
||
---
|
||
|
||
# 如何根据系统主题自动响应CSS深色模式
|
||
|
||
<p align="center">
|
||
<img src="https://cdn.jsdelivr.net/gh/xugaoyi/image_store/blog/20200427163531.jpg" width="500">
|
||
</p>
|
||
|
||
很多人喜欢选择APP或网站中的深色模式,也许他们更喜欢这样的外观,或者他们想让自己的眼睛免受疲劳。这篇文章将告诉你如何在网站中实现一个自动的CSS深色模式,根据访客的系统主题来自动响应。
|
||
|
||
<!-- more -->
|
||
|
||
## CSS 深色模式 (Dark Mode)
|
||
|
||
在`:root`根元素中定义变量来设置主题的颜色。我建议你也这样做,因为这样会使这个过程容易得多。我定义的变量如下:
|
||
|
||
```css
|
||
:root {
|
||
--bg: #fff;
|
||
--textColor: #004050;
|
||
--borderColor: rgba(0,0,0,.15);
|
||
}
|
||
```
|
||
|
||
> **`:root`** 这个 CSS 伪类匹配文档树的根元素。对于 HTML 来说,**`:root`** 表示 `<html>`元素,除了优先级更高之外,与 `html` 选择器相同。
|
||
|
||
如果希望在样式表中使用这些变量,可以这样做
|
||
|
||
```css
|
||
body {
|
||
color: var(--bg);
|
||
}
|
||
```
|
||
|
||
这样,如果你想改变你的主题颜色,所需要做的就是修改你定义的变量,所有使用这个变量的样式都会被更新。
|
||
|
||
现在我们需要定义一组新的变量,这些变量将在调用CSS深色模式时使用。对我来说,深色模式的变量是这样的:
|
||
|
||
```css
|
||
/* 定义深色模式的颜色 */
|
||
:root {
|
||
--bg: rgb(30,30,34);
|
||
--textColor: rgb(150,150,154);
|
||
--borderColor: #2C2C3A;
|
||
}
|
||
```
|
||
|
||
<!-- 广告 -->
|
||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||
<ins class="adsbygoogle"
|
||
style="display:block; text-align:center;"
|
||
data-ad-layout="in-article"
|
||
data-ad-format="fluid"
|
||
data-ad-client="ca-pub-7828333725993554"
|
||
data-ad-slot="5062184441"></ins>
|
||
<script>
|
||
(adsbygoogle = window.adsbygoogle || []).push({});
|
||
</script>
|
||
|
||
|
||
## 添加深色模式自动响应
|
||
|
||
现在我们定义了两组变量。剩下要做的一件事就是将`prefers-color-scheme`媒体查询添加到我们的深色模式变量中。
|
||
|
||
使用您的深色模式变量并在外层添加`@media`查询
|
||
|
||
```css
|
||
/* 根据系统的深色模式响应深色变量 */
|
||
@media (prefers-color-scheme: dark) {
|
||
:root {
|
||
--bg: rgb(30,30,34);
|
||
--textColor: rgb(150,150,154);
|
||
--borderColor: #2C2C3A;
|
||
}
|
||
}
|
||
```
|
||
|
||
> [`prefers-color-scheme`文档](https://developer.mozilla.org/zh-CN/docs/Web/CSS/@media/prefers-color-scheme)
|
||
|
||
这是真的! 如果有人正在使用一个深色模式的系统主题,并访问你的网站,将自动切换到深色模式。
|
||
|
||
> 如果你的电脑系统不支持深色模式,可以使用手机测试,先把手机的系统主题调到深色模式,再打开你的网站。
|
||
|
||
## JS判断深色模式
|
||
如果你的需求需要js来判断系统是否处于深色模式,可以这样做:
|
||
```js
|
||
if(window.matchMedia('(prefers-color-scheme: dark)').matches){
|
||
//深色主题
|
||
}
|
||
```
|
||
> [`matchMedia`](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia)方法返回一个[`MediaQueryList`](https://developer.mozilla.org/zh-CN/docs/Web/API/MediaQueryList)对象,该对象具有属性`matches`、`media`,具有方法`addListener`、`removeListener`。
|
||
|
||
`addListener`接收一个`MediaQueryList`对象作为参数。
|
||
为深色模式添加监听器,以响应系统切换到或切换出深色模式:
|
||
```js
|
||
let listeners={
|
||
dark:(mediaQueryList )=>{
|
||
if(mediaQueryList.matches){
|
||
alert('您切换到深色模式了!')
|
||
}
|
||
},
|
||
light:(mediaQueryList)=>{
|
||
if(mediaQueryList.matches){
|
||
alert('您切换到浅色模式了!')
|
||
}
|
||
}
|
||
}
|
||
|
||
window.matchMedia('(prefers-color-scheme: dark)').addListener(listeners.dark)
|
||
window.matchMedia('(prefers-color-scheme: light)').addListener(listeners.light)
|
||
```
|
||
|
||
## 结论
|
||
|
||
我们不仅可以在布局方面响应不同尺寸屏幕,还可以按系统主题响应深色模式。我相信你的深夜访客,或者那些喜欢深色模式的人,会感谢你的。
|