前言
不知道大家有没有遇到过,网页会根据系统设置的外观模式,显示不同的主题样式。这是如何实现的呢?
1、核心原理:认识 prefers-color-scheme 媒体查询
CSS原生媒体特性 prefers-color-scheme 是实现主题自动切换的核心,它能检测用户操作系统(Windows、macOS、iOS、Android 等)的主题设置,返回三个可能值:
- light:用户设置浅色主题
- dark:用户设置深色主题
- no-preference:用户未设置(默认按浅色处理)
能覆盖绝大多数现代设备,无需额外 JS 即可实现基础切换。
2、案例实现
2.1 定义浅色主题
先在:root中定义浅色主题的基础变量:
css
@media(prefers-color-scheme: light) {
:root {
--bg-color: #ffffff;
/* 浅色背景 */
--text-color: #333333;
/* 浅色文字 */
}
}
2.2 定义深色主题
通过 @media (prefers-color-scheme: dark) 覆盖深色主题的变量:
css
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #121212; /* 深色背景(避免纯黑) */
--text-color: #e5e7eb; /* 浅色文字(避免纯白) */
}
}
2.3 页面使用
在页面样式中统一使用 CSS 变量,无需重复编写明暗逻辑:
如何监听系统模式的变化:可以监听prefers-color-scheme: dark的变化,当matches为true时,为深色模式。
js
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {});

js
body {
background-color: var(--bg-color);
color: var(--text-color);
font-size: 16px;
}
可以在谷歌浏览器中设置切换:

效果如下:
深色:

浅色:

3、如何简写
上面的写法稍微有点复杂,可以使用CSS 的 color-scheme和 light-dark()函数 ,来实现 根据系统主题(深色/浅色模式)自动切换背景和文字颜色 的效果。
js
:root {
color-scheme: light dark;
}
body {
background-color: light-dark(#ffffff, #121212);
color: light-dark(#333333, #e5e7eb);
font-size: 16px;
}
告诉浏览器和操作系统,这个网页 支持浅色(light)和深色(dark)两种主题模式 ,CSS新增的 light-dark()函数 ,允许你 在一个声明里同时为浅色模式和深色模式定义颜色。
4、用户手动切换主题
虽然系统自动切换已满足大部分需求,但提供手动切换按钮能提升灵活性,核心思路是通过 JS 覆盖 CSS 变量,步骤如下:
- 添加切换按钮:
css
theme-toggle">切换深色模式</button>
- 编写 JS 逻辑:
ini
const themeToggle = document.getElementById('theme-toggle');
const html = document.documentElement;
// 初始化:根据系统主题设置按钮文本
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
themeToggle.textContent = isDark ? '切换浅色模式' : '切换深色模式';
// 切换主题
themeToggle.addEventListener('click', () => {
const isCurrentlyDark = html.classList.contains('dark');
if (isCurrentlyDark) {
html.classList.remove('dark');
themeToggle.textContent = '切换深色模式';
} else {
html.classList.add('dark');
themeToggle.textContent = '切换浅色模式';
}
});
- 补充 CSS 样式:
css
/* 手动切换深色模式时的样式覆盖 */
:root.dark {
--bg-color: #121212;
--text-color: #e5e7eb;
}
/* 优先级:手动切换 > 系统主题 */
@media (prefers-color-scheme: dark) {
:root:not(.dark) { /* 未手动切换时,遵循系统主题 */
--bg-color: #121212;
--text-color: #e5e7eb;
}
}
总结
最后总结一下:系统主题自动切换的核心是通过 CSS 原生 prefers-color-scheme 媒体查询,结合 CSS 变量实现网页系统明暗主题自动切换。