Hello,大家好,我是 Sunday。
说起主题切换,很多同学肯定是不陌生的。在过去我的很多课程中都讲到了主题切换的功能。它的实现原理简单一句话描述就是:通过不同的状态标记(light || dark),使用不同的 css,从而达到不同的样式。
如果使用 原生 css 实现的话,那么则需要借助 @media (prefers-color-scheme: <value>),代码大概是这样的:
@media (prefers-color-scheme: dark) {
body {
color: #fff;
background-color: #222;
}
}
@media (prefers-color-scheme: light) {
body {
color: #333;
background-color: #fff;
}
}
这样的代码标记着我们需要在 dark 模式下指定一套 css,然后在 light 模式下指定另外一套 css。虽然可以实现主题切换的功能,但它的缺点也很明显:
- 代码冗长:需要为每个模式定义单独的样式块。
- 维护困难:当项目中有大量深浅模式样式时,修改和扩展变得复杂。
因此,这种方式并不被我们所喜欢(大家在工作中应该也很少见这样的代码),导致我们更多的时候会使用一些库(如:tailwindcss)来实现主题切换。
但是,随着一个全新的 css 属性函数 light-dark(),一切不一样了!
图片
1. 什么是 light-dark()?
1.1 基本特性
light-dark() 是一种新的 CSS 属性值函数,用于在 浅色模式 和 深色模式 下分别指定不同的样式值。
以往我们需要使用 @media (prefers-color-scheme) 媒体查询来处理深浅模式,代码量大且重复。而 light-dark() 通过一个简单的函数调用,直接在单条样式规则中定义深浅模式的不同表现,大大简化了开发工作。
// <light-value> 浅色模式下的样式值。
// <dark-value> 深色模式下的样式值。
property: light-dark(<light-value>, <dark-value>);
以设置背景色 + 字体颜色为例,light-dark() 可以轻松在浅色和深色模式之间切换:
// 在浅色模式下,背景色为白色(#ffffff),字体为黑色(#333333)
// 在深色模式下,背景色为深灰色(#1e1e1e),字体为白色(#f0f0f0)
body {
background-color: light-dark(#ffffff, #1e1e1e);
color: light-dark(#333333, #f0f0f0);
}
是不是贼简单了!对比下传统的 @media (prefers-color-scheme: <value>) 的方式,就更能体现出差异了
// 传统的 @media (prefers-color-scheme: ...) 方案
@media (prefers-color-scheme: dark) {
body {
color: #1e1e1e;
background-color: #f0f0f0;
}
}
@media (prefers-color-scheme: light) {
body {
color: #ffffff;
background-color: #333333;
}
}
1.2 进阶用法
除了刚才的基本使用方式之外,light-dark() 还可以与 CSS 变量结合,动态定义深浅模式下的值:
:root {
--bg-color: light-dark(#ffffff, #1e1e1e);
--text-color: light-dark(#333333, #f0f0f0);
}
body {
background-color: var(--bg-color);
color: var(--text-color);
}
通过这种方式,可以轻松实现主题切换的全局样式管理。
2. light-dark() 的兼容性
截至目前(2024年11月),light-dark() 的浏览器支持场景如下:
图片
根据 mdn 的数据,可以看到目前大部分的浏览器都支持了 light-dark() 属性。
如果你的项目使用场景包含旧版本的浏览器,那么可以添加如下兼容方案:
body {
background-color: #ffffff; /* 默认值 */
background-color: light-dark(#ffffff, #1e1e1e);
}