light-dark() 不是现代 CSS 的可靠选择,它在绝大多数真实项目中无法直接使用——浏览器不认、构建工具不转、DevTools 里查不到计算值,写了等于白写。

light-dark() 不是现代 CSS 的可靠选择,它在绝大多数真实项目中无法直接使用——浏览器不认、构建工具不转、DevTools 里查不到计算值,写了等于白写。
你看到的 light-dark(#333, #fff) 示例,要么来自旧文档笔误,要么依赖 PostCSS 插件(如 postcss-light-dark),要么只在 Chrome 124+/Firefox 125+/Safari 17.4+ 中有条件生效,且必须满足三重硬约束::root { color-scheme: light dark; }、参数只能是纯色值、仅用于颜色类属性。漏掉任一条件,整条声明静默失效。
为什么直接写 light-dark() 会完全没效果
浏览器解析器遇到不认识的函数名,直接丢弃该声明,不报错也不警告。你在 DevTools 的 Styles 面板里根本看不到它,getComputedStyle(el).color 返回空字符串或 fallback 值。
-
light-dark(var(--c), #fff)→ 无效:不支持变量、calc、transparent 等非纯色参数 -
border: 1px solid light-dark(#ccc, #444)→ 无效:shorthand 属性不支持函数调用 -
.theme { color-scheme: light dark; }→ 无效:必须写在:root或html上,否则light-dark()不触发 - 用 Vite 4.3、Next.js 13(未升级)、旧版 Webpack 构建 → 会被 CSS 处理器提前剔除,最终 CSS 文件里根本不存在该函数
真正能用的变量方案:@media + :root 变量覆盖
这是目前唯一无需构建工具、兼容性好(Chrome 87+、Firefox 96+、Safari 14+)、行为可预测的路径。
- 所有主题变量统一定义在
:root,例如--text-primary: #333; - 浅色为默认值,深色用媒体查询覆盖:
@media (prefers-color-scheme: dark) { :root { --text-primary: #eee; } } - 所有使用处必须带
var():比如color: var(--text-primary);,漏掉就回退到浏览器默认 - 配合
,才能让原生控件(、滚动条)自动适配
需要手动切换时,别碰 style.setProperty()
用 JS 动态改 document.documentElement.style.setProperty('--bg', '#121212') 是最差实践:它破坏媒体查询逻辑、卡 UI、维护爆炸、新增颜色就得同步改 JS 和 CSS。
- 正确做法是只操作 class:
document.documentElement.classList.add('dark') - 对应 CSS 写成:
.dark { --text-primary: #eee; --bg: #121212; } - 初始化必须早于首屏渲染:在内联
<script></script>中读取localStorage.getItem('theme')并立即设置 class,否则必闪屏 -
@media (prefers-color-scheme: dark)仅作兜底,不能替代用户点击切换
复杂点在于:系统偏好、用户偏好、服务端渲染三者要对齐。比如 SSR 页面首次输出时,服务端不知道客户端偏好,得靠 JS 补切或加 回退逻辑。这层协调,light-dark() 一个字都帮不上。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











