light-dark() 是受限的原生 CSS 函数,仅 Chrome 124+/Firefox 125+/Safari 17.4+ 支持,需 :root 显式声明 color-scheme: light dark,参数仅限纯色值,且仅用于颜色属性;否则失效或被构建工具剔除。

light-dark() 不是浏览器原生支持的 CSS 函数,直接写 color: light-dark(blue, purple) 会被忽略或报错——它只在特定条件下“看起来能用”,但背后全是构建工具或新版本浏览器的隐性依赖。
Chrome 124+ / Firefox 125+ / Safari 17.4+ 中 light-dark() 确实可用,但有硬性前提
它不是“写了就生效”的语法糖,而是受严格限制的原生函数:
-
:root或html必须显式声明color-scheme: light dark,否则整个函数返回unset(不是 fallback,是彻底失效) - 参数只能是纯色值:
#333、rgb(0,0,0)、CanvasText✅;var(--c)、calc()、transparent❌ - 仅适用于颜色相关属性:
color、background-color、border-color✅;font-size、padding、border(shorthand)❌ - 若你用的是 Vite 4.x、Next.js 13(未升级)、旧版 Webpack,
light-dark()很可能被 CSS 处理器提前剔除,根本不会进最终 CSS 文件
为什么你在 DevTools 里看不到效果?
常见失效场景:
- 写了
light-dark(#333, #fff),但:root没加color-scheme: light dark→ 浏览器静默丢弃整条声明 - 把
color-scheme写在.app上,或用 JS 动态加到 body →light-dark()完全不识别 - 用了
border: 1px solid light-dark(#ccc, #444)→ shorthand 解析失败,整条border声明无效 - 在 iOS Safari 17.2 或微信 X5 内核中测试 → 这些环境仍不支持该函数,回退为无样式
真正稳定、零构建依赖的替代方案
用标准 @media (prefers-color-scheme: dark) 配合 CSS 变量,兼容性好(Chrome 87+、Firefox 96+、Safari 14+),且语义清晰:
- 所有颜色统一抽成变量,例如
--text-primary、--border - 在
:root中定义默认值(浅色):--text-primary: #333 - 在媒体查询中覆盖深色值:
@media (prefers-color-scheme: dark) { :root { --text-primary: #eee; } } - 所有使用处必须带
var():比如color: var(--text-primary),漏掉就回退到浏览器默认 - 配合
<meta name="color-scheme" content="light dark">才能让<input>、滚动条等 UA 控件自动适配
想保留 light-dark() 写法?必须确认三点
否则就是埋雷:
立即学习“前端免费学习笔记(深入)”;
- 你的浏览器版本是否 ≥ Chrome 124 / Firefox 125 / Safari 17.4?查
navigator.userAgent或用matchMedia('(prefers-color-scheme: dark)').matches交叉验证 - 构建工具是否已升级并禁用旧 PostCSS 插件(如
postcss-light-dark)?重复处理会导致规则冲突 - 有没有漏掉系统色兜底?比如
background-color: light-dark(Canvas, Canvas)比light-dark(#fff, #121212)更稳,但不能透明
light-dark() 的陷阱不在语法,而在它把“构建时”和“运行时”的边界模糊了——你以为写一行就搞定,实际要同时对齐浏览器能力、构建链路、HTML 元数据、CSS 作用域四层条件。稍有遗漏,样式就消失得无声无息。


















