CSS color-scheme 和夜間模式

XboxYan 發表於 2022-07-18
CSS
歡迎關注微信公眾號:前端偵探

介紹一個和深色模式相關的CSS屬性:color-scheme

一、什麼是 color-scheme?

color-scheme顧名思義,即為“配色方案”,在系統中指的是“白天模式”和“夜間模式”。使用這個屬性可以輕鬆的更改瀏覽器的預設配色方案,語法如下

color-scheme: normal;
color-scheme: light;
color-scheme: dark;
color-scheme: light dark;

幾個關鍵詞如下

normal:表示元素未指定任何配色方案,因此應使用瀏覽器的預設配色方案呈現。
light:表示可以使用作業系統亮色配色方案渲染元素。
dark:表示可以使用作業系統深色配色方案渲染元素。

下面來看一個簡單的例子

<h2>前端偵探</h2>
<button>關注我</button>

在無任何CSS的情況下,效果如下

image-20220702164619190

如果將系統配色設定為深色模式,由於什麼都沒有做,當然也不會有什麼變化,如下

image-20220702164803001

現在在根元素上新增color-scheme屬性

:root{
  color-scheme: light dark
}

這裡設定兩個值,表示可選的配色方案,由系統來決定。

官方文件上雖然說是優先選擇,實測兩種順序沒有區別,有知道的小夥伴可以留言指點

效果如下

Kapture 2022-07-02 at 17.19.10

是不是非常神奇?平平無奇的頁面馬上就支援深色模式了。

還可以指定單個值,這樣就和系統配色無關了,比如

:root{
  color-scheme: dark
}

這樣在淺色模式下也能以深色主題來渲染,效果如下

image-20220702172224904

二、color-scheme 的作用範圍

通過上面的例子看著好像很強大,是不是可以一鍵生成“深色”模式了?其實不然,color-scheme 的作用範圍很有限,包括表單控制元件滾動條CSS 系統顏色的使用值

1. 表單元素

先看錶單元素,就拿 checkbox來說吧

<input type="checkbox">

image-20220702174426988

假設現在我們需要做一個深色模式的主題,手動將頁面背景設定為黑色

body[dark]{
  background: #000
}

image-20220702174537277

是不是感覺到未勾選狀態有點太過刺眼了呢?

這時,就可以用到color-scheme了,可以將表單元素以深色模式渲染

body[dark]{
  background: #000;
  color-scheme: dark
}

image-20220702174854928

這樣是不是柔和多了?這裡選中的主題色貌似也發生了變換,這個是瀏覽器為了方便夜間瀏覽預設設定的,如果你不希望這個選中顏色,可以用accent-color來覆蓋

body{
  accent-color: #0175ff
}

效果如下

image-20220702183201037

accent-color可以更改表單元素的預設顏色,有興趣的可以參考張鑫旭的這篇文章 CSS accent-color屬性簡介

下面是其他表單元素的深色模式

image-20220704163752288

2. 滾動條

color-scheme也能改變滾動條的配色模式。這個在 windows 下比較明顯,預設淺色模式下,滾動條是這種灰白色的

企業微信截圖_16567581171385

如果在沒有自定義滾動條的情況下(很多設計覺得預設滾動條挺好看的),設計了一套深色主題,可能就變成了這樣

企業微信截圖_16567561585032

滾動條是不是顯得非常突兀?是不是隻能通過偽類自定義滾動條樣式了呢?現在有了color-scheme就不需要這麼麻煩了,直接設定如下

body[dark]{
  color-scheme: dark
}

這樣是不是和諧多了?

image-20220702184405473

其實 MDN 官網已經這麼做了,上面只是臨時遮蔽了這一屬性

企業微信截圖_16567586027558

3. CSS 系統顏色

系統顏色指的是瀏覽器內建的一些顏色。比如前面的button,為什麼能自動渲染成深色模式呢?除了因為它是表單元素外,最根本的一點是這些表單元素的預設樣式上使用了系統顏色。注意看下面這個截圖

image-20220703112802452

可以看到,button的預設樣式裡,使用到了一些系統顏色

button{
  /**/
  color: buttontext;
  background-color: buttonface;
  border-color: buttonborder;
}

這裡的buttontextbuttonfacebuttonborder就是系統顏色了,它會根據color-scheme自動適應深色模式

image-20220703113337440

這些系統顏色不僅僅可以用在表單元素上,也能用在普通元素上,比如這裡取按鈕文字顏色buttontext

div{
  background-color: buttontext;
}

這個顏色會在深色模式下自動變成白色,如下

image-20220703114939552

如果手動的指定了一些正常顏色,那麼也就失效了

button{
  color: #333
}

image-20220703122050588

所以,綜合上面所述,只有系統相關的樣式和顏色才可以受到color-scheme的影響。

完整的 CSS 系統顏色可以參考官方 MDN 文件 ,比較有限,而且顏色都是那種黑白等高飽和度顏色,酌情使用

三、color-scheme 和 prefers-color-scheme

相比color-scheme,大家可能更熟悉prefers-color-scheme,它用於檢測使用者是否有將系統的主題色設定為亮色或者暗色。

.day   { background: #eee; color: black; }
.night { background: #333; color: white; }

@media (prefers-color-scheme: dark) {
  .day.dark-scheme   { background:  #333; color: white; }
  .night.dark-scheme { background: black; color:  #ddd; }
}

那麼,它和color-scheme有什麼聯絡呢?舉個例子

:root{
  color-scheme:  dark;
}
@media (prefers-color-scheme: dark) {
  body {
    color: red
  }
}
請問,在淺色模式下,body 的顏色是什麼?

🤔

🤔

🤔

🤔

🤔

🤔

下面來看實際結果

image-20220703120956764

只有當系統真正切換到深色模式,才會變成紅色

image-20220703121100050

所以結論是,color-schemeprefers-color-scheme沒有必然聯絡,並不會干涉prefers-color-scheme的判斷,但是是相輔相成的,color-scheme 可以更好的處理系統預設的一些樣式,而 prefers-color-scheme可以更方便的自定義其他普通樣式。

四、總結一下

綜上所述,為了更好的支援深色模式,可以在常規的深色模式下新增color-scheme作為兜底方案,可以很好的適配瀏覽器原生樣式

:root{
  color-scheme: light dark
}

這樣一個小知識點,學到了嗎?下面是本文要點總結

  1. color-scheme 是原生支援的配色方案,支援“白天模式”和“夜間模式”,可以輕鬆的更改瀏覽器的預設配色方案
  2. color-scheme 支援的物件有表單控制元件滾動條CSS 系統顏色
  3. CSS 系統顏色指的是瀏覽器內建的顏色,這些顏色是動態的
  4. 但是系統顏色比較有限,而且顏色都是那種黑白等高飽和度顏色,酌情使用
  5. 媒體查詢 prefers-color-scheme 不會受到 color-scheme 的影響,只和系統設定有關
  6. 平時使用中 color-scheme 和 prefers-color-scheme 需要相互配合, color-scheme 適配原生,prefers-color-scheme 適配自定義

然後提一下相容性,其實對版本要求還挺高的

image-20220706152054928

但是,這並不影響我在專案中使用。原因很簡單,這算得上是漸進增強的屬性,即使瀏覽器不支援,也不會對頁面造成什麼影響,如果支援,體驗會更好。所以,趕緊使用起來吧,就一行程式碼的事,無形之中提示了視覺體驗。

最後,如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉發❤❤❤

歡迎關注微信公眾號:前端偵探