直接生效的前提是:root中所有主题变量必须先定义浅色默认值,再用@media (prefers-color-scheme: dark)整体覆盖,且该媒体查询块必须置于所有默认样式之后;漏定义变量、顺序颠倒、未声明color-scheme: light dark,均会导致深色模式失效——根本原因在于css层叠规则严格按声明顺序执行,而非媒体查询自动提升优先级。

为什么写了 @media (prefers-color-scheme: dark) 却没切换
不是媒体查询不触发,而是 CSS 层叠规则在“默默执行”。@media 块本身不提升优先级,只靠声明顺序覆盖。
- 常见错误:深色规则写在浅色样式之前,结果被后面无条件的
:root覆盖 - 嵌套写法失效:
@media (max-width: 768px) { @media (prefers-color-scheme: dark) { ... } }在旧版 Safari(≤13.3)中完全不匹配 - 动态插入的
<style></style>或 JS 创建的CSSStyleSheet,部分浏览器不会重新评估prefers-color-scheme - 变量未初始化:如果
:root里根本没声明--bg-base,深色块里再赋值也无效——变量作用域从声明那一刻起才存在
:root 变量怎么初始化才不翻车
所有变量必须在 :root 中明确定义一次,默认值以浅色为基准;深色块里只改值,不新增变量名。
- 错例:
:root { --bg: #fff; } @media (prefers-color-scheme: dark) { :root { --bg: #121212; } }—— iOS 13.3 以下 Safari 可能忽略后者 - 正例:先写完整
:root默认块,再紧跟@media覆盖,变量名带语义,如--color-bg-surface而非--bg1 - 必须提供 fallback:
background: var(--bg-surface, #fff);,否则变量未定义时会继承或退成透明 - 别依赖浏览器自动映射系统色:用了
var(--text-primary),就得在媒体查询里显式赋值,不能指望CanvasText自动生效
表单、SVG、滚动条这些“隐形元素”怎么一起切
它们不读取 CSS 变量,也不响应 color 或 background 的间接变化,必须显式重置。
- 加
color-scheme: light dark;到:root或html,这是通知浏览器“我支持双主题”,让原生控件(input、select、滚动条等)自动适配 -
svg的fill和stroke必须写成fill: var(--icon-primary);,不能靠currentColor或继承 - 滚动条需单独声明:
::-webkit-scrollbar-track { background: var(--scrollbar-track); } - 表单控件建议重置关键属性:
input, textarea { background: var(--form-bg); color: var(--form-text); border-color: var(--border-color); }
颜色值选得太保守,导致深色模式“灰蒙蒙”
系统深色 ≠ 纯黑底+纯白字。对比度不足、彩度过低、层次缺失,都会让用户觉得“开了但没完全开”。
- 背景推荐
#121212(Material)、#1e1e1e(VS Code)或#1a1a1a,避免#000刺眼 - 文字色用
#e0e0e0~#f0f0f0,小字号慎用#fff,易发虚 - 分割线别用
#333,在#1e1e1e上几乎不可见,换成rgba(255, 255, 255, 0.08)或#303030 - 强调色要验 WCAG:深色下
#2196f3对比度可能不足,换成#42a5f5更稳
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











