你以为暗色模式只能靠两套 media query?CSS 今天用一行 light-dark() 把这件事彻底原生化了

配了三年 CSS,每次加暗色模式都像在写两份代码——10 个颜色变量就是 20 套声明,改一个主色要翻遍整个样式表。

这件事,CSS 今天用一行 light-dark() 彻底原生化了。

light-dark() 是 CSS Color Module Level 5 的函数,2024 年 5 月进入 Baseline Widely Available,到 2026 年全球覆盖率 88.78%。Chrome 123+、Safari 17.5+、Firefox 120+ 全部支持。它的工作方式很简单:给两个颜色值,浏览器根据当前配色方案自动返回对应的那个。

用法:一个函数替代两套 media query

:root {
  /* 告诉浏览器你支持哪些配色方案 */
  color-scheme: light dark;
  /* 现在 light-dark() 生效了 */
  --bg: light-dark(#ffffff, #1a1a1a);
  --text: light-dark(#1a1a1a, #e5e5e5);
}

light-dark(light值, dark值),浏览器读取当前生效的 color-scheme 值——来自系统偏好或手动设置——自动返回对应那个。10 个颜色变量从 20 套声明变成 10 行,一目了然。

一个必须注意的前提: light-dark() 依赖 color-scheme 属性工作。如果忘了声明 color-scheme: light dark,浏览器默认走 light,你永远只拿到第一个参数——不会报错,不会警告,暗色模式静默失效。

配合 CSS 变量:三层令牌架构

light-dark() 最强大的用法不是单独出现,而是配合 CSS 变量的三层令牌体系:

/* 第一层:原语颜色,原始值 */
:root {
  --white: #ffffff;
  --gray-900: #111827;
  --blue-500: #3b82f6;
}

/* 第二层:语义颜色,用 light-dark() 自动切换 */
:root {
  color-scheme: light dark;
  --color-bg: light-dark(var(--white), var(--gray-900));
  --color-text: light-dark(var(--gray-900), #e5e5e5);
  --color-accent: light-dark(var(--blue-500), #60a5fa);
}

/* 第三层:组件直接用令牌,不需要知道它怎么定义的 */
.card {
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid light-dark(rgba(0,0,0,0.1), rgba(255,255,255,0.1));
}

改主色?只动原语层 --blue-500,整个系统自动更新。配合同样是 CSS Color Level 5 的 color-mix(),还能在暗色下给颜色掺入一点蓝色,让暗色主题不单调:

--color-accent: light-dark(
  var(--blue-500),
  color-mix(in oklch, var(--blue-500) 80%, #1a1a1a)
);

兼容旧浏览器:渐进增强

/* 旧浏览器:只走暗色默认值 */
:root {
  --color-bg: #1a1a1a;
  --color-text: #e5e5e5;
}

/* 现代浏览器覆盖,用 @supports 检测 */
@supports (color: light-dark(red, red)) {
  :root {
    color-scheme: light dark;
    --color-bg: light-dark(#ffffff, #1a1a1a);
    --color-text: light-dark(#1a1a1a, #e5e5e5);
  }
}

不识别 light-dark() 的旧浏览器会忽略掉 @supports 块里的声明,保留最初的默认值。整个过程不破坏任何东西。

浏览器支持:已经是生产安全级别

light-dark() 从 2024 年 5 月 Baseline Widely Available,到 2026 年 6 月全球覆盖率 88.78%。主流环境全部支持:

  • Chrome 123+ / Edge 123+
  • Safari 17.5+ / iOS Safari 17.5+
  • Firefox 120+

对 2026 年的项目来说,除非你的用户群还在用很老的 Firefox 版本(Firefox 119 及以下),基本可以直接用,不需要 polyfill。

三个下一步

1. 加上 color-scheme: light dark
:root 加一句 color-scheme: light dark;,这是 light-dark() 的开关,不加它函数不工作。

2. 选一个 CSS 变量改造
找一个项目中已经写了 @media (prefers-color-scheme: dark) 的颜色变量,用 light-dark(light值, dark值) 替换,感受一下代码从 4 行变 1 行的体验。

3. 试试 color-mix() + light-dark() 组合
暗色模式下颜色容易发闷,用 color-mix(in oklch, var(--brand) 80%, oklch(20% 0 0)) 给暗色基调加一点品牌色,整个配色马上有品牌感。这两个函数配合,是目前 CSS 最强大的配色组合拳。


light-dark() 是 CSS Color Level 5 规范的成员,和之前聊过的 color-mix()、相对颜色语法、alpha()contrast-color() 是一个体系的——分别负责颜色混合、颜色派生、透明度调整、对比色计算、暗色方案切换,补完了现代 CSS 颜色处理的最后一环。

评论区

0 条评论

登录后可评论。