近幾年,各個主流操作系統都逐漸開始重視暗色模式,從而改善用戶在環境光亮低時的閱讀體驗。隨着水果在 iOS 13 與 macOS Mojave 中添加了暗色模式,除了 Linux 以外所有的主流操作系統都已經實現了系統層級的暗色模式。Linux 由於 DE、WM 的種類繁雜暫時沒有統一的標准,但目前可以通過暗色 GTK+ 主題、瀏覽器插件等方式實現“偽全局”暗色模式。既然有了系統層級的適配,瀏覽器就可以讀取暗色模式開關,從而實現網頁的自適應。這就是新標准 prefers-color-scheme。
prefers-color-scheme 是什么
W3C 在 2020 年 7 月 31 日發布的 Media Queries Level 5 標准草案 中提到了新的屬性 prefers-color-scheme,網頁現在可以通過條件規則組來獲取瀏覽器宿系統的暗色模式狀態並應用了。也就是說,現在我們可以很簡單地實現“暗色模式系統訪問的頁面是暗色的,亮色模式系統訪問的頁面是亮色的”。
prefers-color-scheme 怎么用
可以參考 MDN 關於 prefers-color-scheme 的 描述。
prefers-color-scheme 有 2 種值:
light——瀏覽器宿系統使用亮色主題的界面,同時也是默認值,瀏覽器 privacy.resistFingerprinting 被設置為 true 時返回的也將是這個值
dark——瀏覽器宿系統使用暗色主題的界面
還有一個已廢棄的值:
no-preference——瀏覽器宿系統使用未知主題的界面,當較舊版本的瀏覽器在宿系統不支持系統層級的暗色模式時會返回這個值,較舊版本的瀏覽器 privacy.resistFingerprinting 被設置為 true 時返回的也將是這個值
通過條件規則組就可以作出判斷。
CSS
@media (prefers-color-scheme: dark) {
// 暗色模式樣式
}
@media not (prefers-color-scheme: dark) {
// 非暗色模式樣式
}
JavaScript
只使用 CSS 條件規則很難實現某些需求,我們可以對 window 使用 matchMedia 方法得到的 Media 使用 matches 方法來獲取系統暗色模式狀態:
if (window.matchMedia('prefers-color-scheme: dark').matches) {
// 是暗色模式做什么
} else {
// 非暗色模式做什么
}
另外還可以監聽系統暗色模式的狀態,在系統開關暗色模式時作出反應:
window.matchMedia('(prefers-color-scheme: dark)').addListener(e => {
if (e.matches) {
// 系統開啟暗色模式后做什么
} else {
// 系統關閉暗色模式后做什么
}
});
兼容性
其實 prefers-color-scheme 也不是什么新東西了,去年水果就已經在 macOS Mojave 上的 Safari 中添加了它,隨后各瀏覽器不斷跟進,現在的兼容性還算不錯: