light-dark() 在旧浏览器中完全不识别,会静默丢弃;必须用 @media (prefers-color-scheme) 配合 :root 变量和 var() 调用,且 color-scheme 声明与 meta 标签缺一不可。

light-dark() 在旧浏览器里直接失效,不是降级而是彻底不识别
你写的 color: light-dark(#333, #fff) 在 Chrome 123、Firefox 124 之前,或任何 Safari 17.4 之前的版本中,CSS 解析器会把它当作文法错误静默丢弃——不会 fallback 到第一个值,也不会报错,getComputedStyle 返回的永远是初始值或继承值。这不是“没生效”,是根本没进样式计算流程。
必须用 @media (prefers-color-scheme) 替代,且不能省略 :root 变量定义
稳定可落地的写法只有这一种组合,缺一不可:
-
:root中先定义默认(浅色)变量:--text-primary: #333; - 再用媒体查询覆盖深色值:
@media (prefers-color-scheme: dark) { :root { --text-primary: #eee; } } - 所有使用处必须显式调用:
color: var(--text-primary);—— 漏掉var()就退化为浏览器默认色 - 若需强制某区域走深色(比如弹窗),加 class 并覆盖:
.modal-dark { --text-primary: #ddd; }
构建工具里模拟 light-dark() 写法要小心三类陷阱
PostCSS 插件(如 postcss-dark-mode)或 Sass 函数能转译 light-dark(),但实际输出的是两套独立规则,容易引发问题:
- 重复声明冲突:同一选择器在多个文件里用了
light-dark(),最终 CSS 可能出现多条color: #333和@media块,后写的覆盖前写的 - 变量未提升:如果
light-dark(var(--c1), var(--c2))中的--c1是在子组件里定义的,转译时无法读取,直接报错或留空 - 伪类里误用:
button:hover { background: light-dark(#f0f0f0, #333); }会被转成 hover + media 组合,但实际行为仍是系统偏好决定,不是悬停触发
最易被忽略的兼容性锚点:color-scheme 声明位置和 meta 标签
即使你用了 @media (prefers-color-scheme),某些 UA 控件(如 <input type="date">、滚动条、select 下拉箭头)仍不会自动变色,除非同时满足:
-
:root或html元素上写了color-scheme: light dark; - HTML
里加了<meta name="color-scheme" content="light dark"> - 这两个声明缺一不可;只写 CSS 的
color-scheme,iOS Safari 16.6+ 以下仍不触发原生控件适配
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











