传统深色模式的问题
传统上,实现深色模式需要将重复的 CSS 规则封装在 @media (prefers-color-scheme: dark) 中:
:root {
--bg: #ffffff;
--text: #111111;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #1a1a2e;
--text: #e0e0e0;
}
}
这可行,但会产生维护开销,特别是在跨大型样式表管理多个颜色属性时。 light-dark() CSS 函数完全消除了这种重复。
light-dark() 函数
light-dark() 函数接受两个颜色值并自动返回与用户当前配色方案匹配的颜色值:
color: light-dark(black, white);
/* Returns black in light mode, white in dark mode */
第一个参数是浅色模式颜色,第二个参数是深色模式颜色。该函数尊重用户的系统首选项或 color-scheme 属性。
设置配色方案
为了使 light-dark() 正常工作,您必须声明页面支持哪些配色方案:
<meta name="color-scheme" content="light dark" />
或者在 CSS 中:
:root {
color-scheme: light dark;
}
这告诉浏览器页面支持这两种方案并启用 light-dark() 函数。
简化主题变量
使用 light-dark() ,前面的示例变成单个声明:
:root {
color-scheme: light dark;
--bg: light-dark(#ffffff, #1a1a2e);
--text: light-dark(#111111, #e0e0e0);
--primary: light-dark(#2563eb, #60a5fa);
--border: light-dark(#d1d5db, #374151);
--shadow: light-dark(rgba(0,0,0,0.1), rgba(0,0,0,0.4));
}
无需媒体查询。浏览器会自动处理切换。
比较:Media Query 与 light-dark()
| 方面 | @media 更喜欢颜色方案 | 明暗() |
|---|---|---|
| 代码行数 | 每个变量对 ~10 | 每个变量 1 个 |
| 保养 | 双块更新 | 单线 |
| JavaScript 切换 | 需要手动切换类 | 兼容配色方案覆盖 |
| 浏览器支持 | 通用 | Chrome 123+、Firefox 128+、Safari 17.5+ |
| 粒度 | 每块 | 每个值 |
以编程方式切换
对于手动主题切换(不仅仅是系统首选项),请更改根元素上的 color-scheme :
// Toggle between light and dark manually
document.documentElement.style.colorScheme =
document.documentElement.style.colorScheme === "dark"
? "light"
: "dark";
这与 light-dark() 无缝配合,因为该函数读取当前 color-scheme 值。
与复杂主题的自定义属性相结合
为了完全控制,请将 light-dark() 与语义自定义属性结合起来:
:root {
color-scheme: light dark;
/* Surface colors */
--surface-primary: light-dark(#ffffff, #0f172a);
--surface-secondary: light-dark(#f8fafc, #1e293b);
/* Text colors */
--text-primary: light-dark(#0f172a, #f1f5f9);
--text-secondary: light-dark(#475569, #94a3b8);
/* Accent colors */
--accent: light-dark(#3b82f6, #818cf8);
--success: light-dark(#22c55e, #4ade80);
--danger: light-dark(#ef4444, #f87171);
}
浏览器支持和后备
截至 2026 年,Chrome 123+、Firefox 128+ 和 Safari 17.5+ 支持 light-dark()。对于较旧的浏览器,请提供后备值:
.button {
/* Fallback for older browsers */
background: #2563eb;
/* Modern override */
background: light-dark(#2563eb, #1d4ed8);
}
迁移策略
- 将
color-scheme: light dark添加到:root - 将
@media块替换为自定义属性中的light-dark()函数调用 - 使用 DevTools 渲染选项卡测试这两个主题
- 验证后删除旧的
@media块 - 添加 JavaScript 切换支持以手动主题切换
结论
CSS light-dark() 代表了暗模式实现的显着简化。通过消除重复的代码块并让浏览器本地处理主题切换,开发人员可以以更少的认知开销维护更清晰的样式表。这是一个罕见的例子,新的 CSS 功能同时减少了代码大小、提高了可维护性并增强了用户体验。

