唯一可靠方式是用 window.matchmedia('(prefers-color-scheme: dark)') 实时检测系统暗黑模式,需监听 change 事件更新 data-theme 和 localstorage,并在初始化时同步设置;css 通过 [data-theme="dark"] 控制变量,媒体查询本身不触发 js 行为。

直接用 window.matchMedia('(prefers-color-scheme: dark)') 检测,这是唯一可靠方式。它返回一个 MediaQueryList 对象,.matches 属性实时反映系统当前是否启用暗黑模式,不能靠 class 名或 localStorage 伪造判断。
必须监听变化,不能只查一次
很多人在页面加载时读一次就完事,结果用户在系统设置里切换了深色模式,网页毫无反应。正确做法是绑定 change 事件:
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
mediaQuery.addEventListener('change', e => {
const isDark = e.matches;
document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
});
初始化时也要同步检查
页面刚打开时,需立刻根据系统偏好设好主题,并存入 localStorage(若用户没手动选过):
- 先查
localStorage.getItem('theme'),有值就用它; - 没值就取
mediaQuery.matches,再写回 localStorage。
CSS 里用属性选择器响应
别写两套冗余样式,统一用 html[data-theme="dark"] 控制变量:
:root {
--bg: #ffffff;
--text: #333333;
}
html[data-theme="dark"] {
--bg: #121212;
--text: #e0e0e0;
}
body {
background-color: var(--bg);
color: var(--text);
transition: background-color 0.3s, color 0.3s;
}
注意:媒体查询本身不触发 JS 切换@media (prefers-color-scheme: dark) 只能控制纯 CSS 样式,无法更新 data-theme 属性、无法触发按钮状态、也无法影响 localStorage。想实现“自动适配 + 手动覆盖 + 持久记忆”,JS 监听和 DOM 更新缺一不可。
不复杂但容易忽略
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











