常见错误是写成@media (prefers-color-scheme = dark),等号为语法错误,必须用冒号;正确写法为@media (prefers-color-scheme: dark),且仅响应系统级深色设置,不读取浏览器主题或网页开关,旧版safari支持不稳定。

prefers-color-scheme 媒体查询写法常见错误
直接写 @media (prefers-color-scheme = dark) 会完全失效——等号是语法错误,必须用冒号;@media (prefers-color-scheme: dark) 才是合法写法。它只响应系统级设置(macOS、Windows 11、iOS/iPadOS、Android 10+),不读取浏览器主题或网页内开关。
旧版 Safari(
注意:prefers-color-scheme 只有三个可能值:light、dark、no-preference(极罕见,可忽略)。别把它当布尔值用,也别试图监听“未设置”状态。
为什么不能只靠 media query 实现可用的暗黑模式
它只告诉你“系统倾向”,不代表用户当前想要深色。比如:夜间在手机上刷技术文档,系统设了 dark,但你刚点开一段带浅灰 <pre class="brush:php;toolbar:false;"></pre> 的代码块,背景一黑,文字直接糊成一片——这不是适配,是反噬。
用户手动开关(如右上角 ☀️/? 按钮)优先级必须高于系统偏好。这意味着:
- 首次访问时,用
@media (prefers-color-scheme: dark)设默认值 - 一旦用户点击切换,立刻以 localStorage 存储选择,并覆盖系统判断
- 后续加载优先读
localStorage.getItem('theme'),没值才 fallback 到媒体查询
用 class 切换比 media query 更可控
把所有暗黑逻辑收口到一个 html 元素上的 class,比如 class="theme-dark",比在 CSS 里重复写十几遍 @media (prefers-color-scheme: dark) 更易维护、更易测试、也更容易和 JS 交互。
示例结构:
:root {
--bg-color: #f0f2f5;
--text-color: #333;
}
.theme-dark {
--bg-color: #121212;
--text-color: #e0e0e0;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s ease, color 0.3s ease;
}
JS 切换只需一行:document.documentElement.classList.toggle('theme-dark')。老浏览器兼容性也简单:.theme-dark body { background: #121212; } 就能兜底。
别滥用 !important 强盖,容易和第三方组件库冲突;用更具体的 selector,比如 .theme-dark .card 或 .theme-dark input[type="range"]。
表单控件和图片的暗黑适配常被忽略
prefers-color-scheme 不会自动翻转 <input type="range"> 的轨道颜色,也不会让 <img> 变成深色版本——这些都得手动处理。
表单建议方案:
- 在
:root中定义--input-bg、--input-border、--input-placeholder等变量 - 在
.theme-dark下重设这些变量,而非单独写input.dark-mode { ... } - 特别注意
focus状态的描边颜色,深色下用rgba(102, 179, 255, 0.5)比纯蓝更柔和
图片处理要谨慎:.theme-dark img { filter: invert(1); } 看似简单,但会导致 logo 反色、彩色图表失真、透明 PNG 出白边。真正可靠的方案是用 srcset + media 属性按需加载不同资源,或者对关键图片加 data-dark-src 属性由 JS 替换。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











