prefers-color-scheme 仅读取系统偏好,需手动编写 light/dark 两套样式并确保变量初始化;必须同时声明两个媒体查询,避免白屏或闪屏,配合 color-scheme 声明和 matchmedia 监听实现可靠适配。

prefers-color-scheme 不是开关,它只是读取系统偏好——页面不会“自动变暗”,你得自己写两套样式并确保它们都生效。
只写 @media (prefers-color-scheme: dark) 就够了吗
不够。常见错误是只在 dark 分支里定义颜色变量或背景色,而 light 模式下这些值没初始化,结果页面在浅色系统里白屏、黑字全糊成一片。
- 必须同时写出
@media (prefers-color-scheme: light)和@media (prefers-color-scheme: dark),哪怕light分支只是显式重置(比如--bg: #fff) - 别嵌套复合查询,例如
@media (max-width: 768px) and (prefers-color-scheme: dark)—— 老版 Safari(12.1 之前)直接忽略整条规则 - 构建工具(如 PostCSS、Vite 插件)可能误删或转义
@media块,上线前检查生成的 CSS 是否还保留着原始媒体查询
:root 里定义 CSS 变量的顺序和位置
CSS 变量不是全局常量,它的值取决于声明顺序和作用域。把所有主题变量一股脑塞进 :root 然后靠媒体查询覆盖,容易漏掉某些变量或被后续样式意外覆盖。
- 基础默认值(不带媒体查询)放
:root,例如--text-primary: #333 - 主题专属值用
@media在:root内覆盖,例如@media (prefers-color-scheme: dark) { :root { --text-primary: #f0f0f0; } } - 避免用
.dark-modeclass 控制变量再靠 JS 切换——这样会和系统偏好冲突,且首次渲染时闪屏明显
如何测试不同模式下的真实表现
不能只靠改系统设置来回刷新,太慢;也不能只信浏览器 DevTools 的模拟开关,有些样式(比如 color-scheme 对滚动条的影响)只在真机或完整渲染流程中才生效。
- Edge / Chrome / Safari DevTools 渲染面板里有
Emulate CSS media feature prefers-color-scheme下拉项,选light或dark后刷新即可预览 - 用
color-scheme: light dark声明在:root或html上,能让表单控件、滚动条等原生元素自动适配,但前提是没被自定义样式完全覆盖 - 无障碍测试时特别注意对比度:同一套文字色在深色背景上可能合规,在浅色背景上就低于 4.5:1,需分别验证
最易被忽略的一点:prefers-color-scheme 是只读信号,它不触发重绘逻辑,也不保证用户切换系统主题时你的 JS 能立刻响应——如果用了 window.matchMedia 监听,记得调用一次 handler 初始化状态,否则首屏永远按旧偏好渲染。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











