快速了解 CSS light-dark 函數(shù)及其應(yīng)用
介紹一個和主題密切相關(guān)的CSS特性:light-dark,有了它,可以更靈活的適配各種主題模式。
一、prefers-color-scheme
一般來講,網(wǎng)站會有三種主題模式,白天、黑夜、自動跟隨系統(tǒng),比如下面的 MDN 官網(wǎng)。
前面兩者是固定的,不會跟隨系統(tǒng)變化。
這里簡單實現(xiàn)一下三種主題模式,假設(shè)有這樣一個結(jié)構(gòu)。
<body>
<h1>前端偵探</h1>
</body>
我們用input radio來實現(xiàn)切換效果。
<body>
<fieldset>
<input type="radio" name="theme" value="light" id="light" checked><label for="light">白天</label>
<input type="radio" name="theme" value="dark" id="dark"><label for="dark">黑夜</label>
<input type="radio" name="theme" value="auto" id="auto"><label for="auto">自動</label>
</fieldset>
<h1>前端偵探</h1>
</body>
簡單修飾一下,效果是這樣的。
通常我們會用 CSS變量來動態(tài)改變主題色,這里簡單一點,就用文字顏色和背景來表示。
:root{
--bg: aliceblue;
--color: #000;
}
白天和黑夜模式比較好實現(xiàn),是固定的,這里直接用:has配合:checked來動態(tài)匹配當(dāng)前選中項,然后改變CSS變量就行了。
實際項目中,如果考慮兼容性,可以用 JS 動態(tài)切換 class 來匹配。
:has(#light:checked){
body{
--bg: aliceblue;
--color: #000;
}
}
:has(#dark:checked){
body{
--bg: #000;
--color: #fff;
}
}
然后就是自動跟隨系統(tǒng)主題色,這個就需要用媒體查詢了,也就是prefers-color-scheme,實現(xiàn)如下:
@media (prefers-color-scheme: light) {
:has(#auto:checked){
body{
--bg: aliceblue;
--color: #000;
}
}
}
@media (prefers-color-scheme: dark) {
:has(#auto:checked){
body{
--bg: #000;
--color: #fff;
}
}
}
這樣就可以實現(xiàn)三種主題模式的動態(tài)切換了,效果如下:
你也可以訪問以下在線鏈接查看實際效果
- CSS prefers-color-scheme (codepen.io)[1]
- CSS prefers-color-scheme (juejin.cn)[2]
二、light-dark 和 color-scheme
除了上面這種方式,現(xiàn)在light-dark也能實現(xiàn)類似的效果。
https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark
light-dark是一個CSS函數(shù),語法很簡單,只需要傳兩個值。
/* 顏色 */
color: light-dark(black, white);
/* 自定義屬性 */
color: light-dark(var(--light), var(--dark));
第一個值是在白天模式下的值,第二個是在黑夜模式下的值。
那這個模式是由什么決定的呢?答案就是color-scheme。
回到前面的例子,如果用light-dark實現(xiàn)會更加簡單。
:root{
--bg: light-dark(aliceblue, #000);
--color: light-dark(#000, #fff);
}
:has(#light:checked){
body{
color-scheme: light;/*白天模式*/
}
}
:has(#dark:checked){
body{
color-scheme: dark; /*黑夜模式*/
}
}
:has(#auto:checked){
body{
color-scheme: light dark; /*自動模式*/
}
}
簡單解釋一下,首先提前定義好白天和黑夜模式下的值,然后在切換主題的時候就不是改值了,而是改color-scheme。
同樣可以實現(xiàn)三種主題模式的動態(tài)切換了,效果如下:
你也可以訪問以下在線鏈接查看實際效果
- CSS light-dark (codepen.io)[3]
- CSS light-dark (juejin.cn)[4]
是不是比前面的實現(xiàn)方式更簡單了,而且思路更加直觀了
三、更靈活的主題適配方式
在實際需求中,不僅僅有黑夜和白天,還有各種各樣的主題色。這些主題色往往還會區(qū)分白天和黑夜,畢竟同一種紅色在白色背景和黑色背景觀感肯定是不同的。
比如下面這種顏色,在黑色背景上就會有些突兀,或者刺眼。
所以,主題色也應(yīng)該區(qū)分白天和黑夜。
下面實現(xiàn)一個主題色和白天/黑夜模式自適應(yīng)搭配的案例。
我們再使用input radio來創(chuàng)建幾個主題色選項。
<fieldset>
<label>主題色</label>
<input type="radio" name="color" value="red" id="red" checked><label for="red">紅色</label>
<input type="radio" name="color" value="blue" id="blue"><label for="blue">藍色</label>
<input type="radio" name="color" value="green" id="green"><label for="green">綠色</label>
</fieldset>
<fieldset>
<label>黑暗/白天模式</label>
<input type="radio" name="theme" value="light" id="light" checked><label for="light">白天</label>
<input type="radio" name="theme" value="dark" id="dark"><label for="dark">黑夜</label>
<input type="radio" name="theme" value="auto" id="auto"><label for="auto">自動</label>
</fieldset>
<button>前端偵探</button>
然后,給每種顏色用 CSS變量定義好,并且每種主題色都包含白天、黑夜兩種顏色,如下:
:root{
--bg: light-dark(aliceblue, #000);
--primary-red: light-dark(rgb(255, 69, 69), rgb(119, 2, 2));
--primary-blue: light-dark(rgb(0, 68, 255), rgb(36, 36, 154));
--primary-green: light-dark(rgb(0, 214, 61), rgb(5, 94, 5));
--primary-color: var(--primary-red);
}
然后在切換主題色時,改變--primary-color就行了。
/*主題色修改*/
:has(#red:checked){
body{
--primary-color: var(--primary-red);
}
}
:has(#blue:checked){
body{
--primary-color: var(--primary-blue);
}
}
:has(#green:checked){
body{
--primary-color: var(--primary-green);
}
}
這樣主題色修改和白天/黑暗模式修改就徹底分離開來,在實現(xiàn)上也更加清晰明了。
下面是實際效果演示,可以明顯看到不同模式下的主題色是不同的。
你也可以訪問以下在線鏈接查看實際效果
- CSS light-dark primary (codepen.io)[5]
- CSS light-dark primary (juejin.cn)[6]
四、兼容性和總結(jié)
再來說一下兼容性,要求 Chrome 123+,雖然是剛推出來不久,但現(xiàn)在(2024-6-22)所有瀏覽器都已經(jīng)兼容了。
這意味著已經(jīng)是一個標準了,放心學(xué)習(xí),下面總結(jié)一下本文要點
- 網(wǎng)站一般會有三種主題模式,白天、黑夜、自動跟隨系統(tǒng)
- 自動跟隨系統(tǒng)主題色,需要用媒體查詢prefers-color-scheme
- light-dark語法很簡單,可以傳兩個顏色,分別是白天模式和黑夜模式的顏色
- light-dark的顏色模式由color-scheme來決定
- light-dark可以以更靈活的方式來適配各種主題色
light-dark可以說是 web 上關(guān)于主題顏色的終極解決方案了,期待可以早日使用。
[1]CSS prefers-color-scheme (codepen.io): https://codepen.io/xboxyan/pen/KKLoEjB。
[2]CSS prefers-color-scheme (juejin.cn): https://code.juejin.cn/pen/7383215058630737972。
[3]CSS light-dark (codepen.io): https://codepen.io/xboxyan/pen/mdYxgVm。
[4]CSS light-dark (juejin.cn): https://code.juejin.cn/pen/7383215549599186954。
[5]CSS light-dark primary (codepen.io): https://codepen.io/xboxyan/pen/LYodvLR。
[6]CSS light-dark primary (juejin.cn): https://code.juejin.cn/pen/7383215899521597474。