2024 啦,我們終于能用 CSS 一行代碼實現暗黑模式了!
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);
}