prefers-color-scheme 是 CSS 媒体查询关键字,用于检测系统深色/浅色偏好,需先写默认浅色样式再用 @media (prefers-color-scheme: dark) 覆盖,配合 localStorage 存用户选择、class 切换和 CSS 变量实现可靠主题切换。

怎么用 prefers-color-scheme 检测系统主题
浏览器能直接读取系统设置的深色/浅色偏好,不用 JS 也能做基础切换。prefers-color-scheme 是 CSS 媒体查询关键字,不是 JS API,别在 window.matchMedia 里拼错成 prefers-dark-scheme —— 那会永远不匹配。
常见错误:只写 @media (prefers-color-scheme: dark) 却没配默认浅色样式,导致深色系统下文字全黑看不清。
- 必须先写基础样式(默认浅色),再用媒体查询覆盖深色规则
- 支持值只有
light、dark、no-preference(极少触发,别依赖) - Safari 12.1+、Chrome 76+、Firefox 67+ 支持;IE 完全不支持,别加前缀
@media (prefers-color-scheme: dark) {
body { background: #121212; color: #e0e0e0; }
}
手动切换时怎么存用户选择并同步到 class
用户点“深色模式”按钮后,得把选择记下来,否则刷新就丢。不能只改 document.body.style.backgroundColor,那只是内联样式,无法批量控制组件,也绕不过 CSS 优先级问题。
正确做法是切 class,比如 theme-dark,再用 CSS 规则批量接管颜色变量。
- 用
localStorage存,别用sessionStorage(关页就清空) - 初始化时先读
localStorage,再 fallback 到prefers-color-scheme,最后设document.documentElement.classList - 别漏掉监听系统变化:
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ...)
CSS 变量怎么配合主题切换不翻车
直接写死 background: #121212 在多个地方?换主题就得全局搜替换。用 CSS 自定义属性(--bg-primary)才是正解,但要注意作用域和继承链。
实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。
容易踩的坑:把变量全定义在 :root 里,结果深色模式下 .theme-dark 没重定义变量,还是用的浅色值。
- 变量定义要分层:基础变量(如
--text-default)放:root,主题变量(如--bg-body)按 class 覆盖 - 深色模式 class 必须比
:root优先级高,推荐用.theme-dark或html.theme-dark - 别在 JS 里反复 setProperty,改 class 就够了,CSS 自动响应
:root {
--bg-body: #ffffff;
}
.theme-dark {
--bg-body: #121212;
}
body { background: var(--bg-body); }
为什么 color-scheme: light dark 很关键
这个 CSS 属性不是可有可无的装饰。它告诉浏览器:“我这页面支持深色模式”,从而让表单控件(、)、滚动条、甚至打印样式自动适配主题。不加的话,深色页面里输入框还是白底黑字,对比度爆炸。
注意它只接受空格分隔的值,不能写成 color-scheme: dark 单独一行——那样会禁用系统默认逻辑,反而更难兼容。
- 必须写在
:root或html上,子元素不会继承生效 - 值只能是
light、dark或两者都写(推荐light dark) - 部分旧版 Chrome 对
color-scheme解析不稳定,建议和prefers-color-scheme一起用
主题切换真正卡住人的地方,从来不是“怎么实现”,而是“什么时候该信系统、什么时候该信用户、什么时候该忽略”。localStorage 里的值、prefers-color-scheme 的媒体查询、color-scheme 的声明,三者职责不同,混着用就乱。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










