正确顺序是先定义 :root 默认变量再写 prefers-color-scheme 媒体查询,禁止嵌套、必须漏定义补全、所有样式用变量驱动、添加 color-scheme 声明、阴影边框用带 alpha 的颜色、确保每个变量都有默认值。

prefers-color-scheme 媒体查询必须写在 :root 之后
浏览器按 CSS 声明顺序覆盖变量,@media (prefers-color-scheme: dark) 如果写在 :root 默认定义之前,深色规则会被后续无条件样式覆盖。iOS 13.3 以下 Safari 还会直接忽略嵌套在其他媒体查询里的 prefers-color-scheme。
- 正确顺序:先完整声明
:root所有默认变量(浅色),再单独写@media (prefers-color-scheme: dark) { :root { ... } } - 禁止嵌套:
@media (max-width: 768px) { @media (prefers-color-scheme: dark) { ... } }在旧版 Safari 中失效 - 漏定义 = 翻车:如果
--border-color只在浅色:root里定义,深色媒体查询中没重置,组件用border: 1px solid var(--border-color, #ccc)就会显示刺眼的亮灰边框
所有主题相关值必须从 CSS 变量取,不能硬编码
把 background: #f8fafc 写死在 .card 里,@media 根本改不动它。深色模式不是“反色”,而是语义化重设——--text-primary 在浅色下是深灰,在深色下应是高对比度浅灰,而非简单改成 #fff。
- 按钮背景、SVG
fill、表单border、滚动条 thumb 都得用var(--btn-bg)、var(--icon-fill)等变量驱动 - 避免
rgba(0,0,0,0.1)这类“默认黑透明”:深色背景下它变亮且突兀,应改用rgba(255,255,255,0.05) - 图标、SVG 必须显式响应:深色下
fill: currentColor或fill: var(--icon-fill),否则白色 SVG 会隐形
color-scheme: light dark 必须加到 :root 或 html
仅靠变量切换不够。不加 color-scheme: light dark,原生控件(input、select、textarea、滚动条)仍按系统默认渲染,常出现深色页面里白底黑字输入框、或滚动条消失等现象。
- 写法:
:root { color-scheme: light dark; }或html { color-scheme: light dark; } - 生效范围:Chrome 85+、Firefox 96+、Safari 13+ 支持,老版本降级为无影响
- 不加后果:即使你重写了所有
input样式,某些系统控件(如 macOS 的datepicker)仍可能保持浅色外观
阴影和边框颜色必须带 alpha,不能只换纯色
box-shadow 和 border-color 依赖颜色变量,但直接塞 #000 或 #fff 会导致深色下阴影“看不见”或边框“融进背景”。关键不是换色,是换透度与明度组合。
- 浅色阴影推荐:
rgba(0, 0, 0, 0.08)、rgba(0, 0, 0, 0.1) - 深色阴影对应:
rgba(255, 255, 255, 0.05)、rgba(255, 255, 255, 0.08) - 别用
lighten()/darken()Sass 函数:它们只调 HSL 明度,不感知背景语义,lighten(#121212, 20%)得到的是不可读的灰
no-preference 或浏览器不支持 prefers-color-scheme 时,:root 中未初始化的变量会回退到浏览器默认值——比如 canvas 背景可能意外变白,导致文字不可读。必须确保每个主题变量都在 :root 里有明确默认值,一个都不能漏。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











