Preferencess-color-scheme:嗨,黑暗,我的老朋友

過度或有需求?全面瞭解深色模式的相關資訊,以及如何善用這類模式為使用者創造優勢!

簡介

深色模式前推出深色模式

綠幕的電腦螢幕
綠幕 (資料來源)

我們成功進入了深色模式, 在個人運算技術的初期,不使用深色模式並不重要 但其實... 單色 CRT 電腦螢幕透過電子光束觸發運作 時,在 CRT 早期使用的哲學是綠色的。 由於文字顯示綠色,其餘部分為黑色,因此這些模型通常稱為 綠幕

黑白文字處理
黑白 (資料來源)

隨後引入的 Color CRTs 顯示了多個顏色 探討紅色、綠色和藍色的哲學 他們同時啟動了這三個哲學,製作出白色的白人。 隨著遊戲問世,所見即所得 電腦發布、 虛擬文件就像一張實體紙張一樣,大受歡迎。

WorldWideWeb 瀏覽器中的深色白色網頁
WorldWideWeb 瀏覽器 (資料來源)

這時就有 dark-on-white 開始出現設計趨勢。 這個趨勢也延續到 舊版文件式網路。 第一個瀏覽器 WorldWideWeb (別忘了 CSS 尚未問世); 以這種方式顯示的網頁。 趣味小知識:第二次瀏覽器 Line Mode Browser (折線模式瀏覽器) 是 黑暗。 現今的網頁和網頁應用程式通常會使用深色文字設計 淺色背景上,系統會在使用者代理程式樣式表中,使用硬式編碼的基準假設,包括 Chrome

躺在床上的智慧型手機
躺在床上的智慧型手機 (資料來源:防潑水)

CRT 的時代很長。 觀看及創作內容已轉向使用行動裝置 採用背光 LCD 或節能的 AMOLED 螢幕。 更小且可移動的電腦、平板電腦和智慧型手機促成了新的使用模式。 享受網路瀏覽、寫程式等休閒工作,以及高檔遊戲 通常是在下班後發生。 使用者甚至在晚間戴著床邊使用裝置。 在昏暗環境中使用裝置的人數越多, 就更難重新回歸黑暗點的想法越來越受歡迎。

為何要使用深色模式

為美感設計深色模式

使用者提問時 為何喜歡或想要深色模式 最熱門的回覆是「眼睛上比較容易」 後面會加上「很棒」的美感 Apple 的 深色模式開發人員說明文件 明確寫字:"您可以選擇是否啟用淺色或深色外觀 是大多數使用者的美學,可能與環境光線條件無關。」

,瞭解如何調查及移除這項存取權。
Mac OS System 7 中的 CloseView,
System 7 CloseView (來源)

深色模式做為無障礙工具

其他人其實需要深色模式,只是當做其他無障礙工具使用。 例如低視能使用者 這類無障礙工具是最早出現的 系統 7CloseView 功能,當中有 「霧黑白」和「黑底白字」。 雖然系統 7 支援色彩,但預設使用者介面仍為黑白。

這些反向實作以色彩導入後可看出其弱點。 使用者研究是由 Szpiro 等人 低視能使用者如何使用運算裝置 所有受訪使用者都不喜歡的倒立圖片 但對於深色背景來說 許多建議使用的淺色文字 Apple 支援一項名為「使用者偏好設定」的功能 Smart Invert、 這會反轉顯示畫面色彩,但圖片、媒體 和一些使用深色樣式的應用程式

電腦視覺症狀 (也稱為數位眼部拉) 是特殊的低視能形式 定義 "由於電腦使用環境的眼睛與視覺障礙, (包括桌上型電腦、筆記型電腦和平板電腦) 和其他電子裝置 (例如 智慧型手機和電子閱讀裝置)。」 已獲建議 青少年使用電子裝置,尤其是在夜間 導致睡眠時間較短的風險增加 睡眠延遲較長的時間,並增加睡眠時間差。 此外,我們透過廣受好評的方式 回報 參與 生理時鐘 以及睡眠週期 與心律不正的環境可能會導致睡眠不足 也可能影響情緒和工作表現 Rosnfield 進行研究。 如要限制這些負面效果,請調整螢幕的色溫,藉此減少藍光 例如 iOS 和 iOS 等Night Shift 或 Android 夜燈可助你一臂之力, 也可以避免透過深色主題或深色模式一般使用亮光或不規則的光線。

AMOLED 螢幕的深色模式節約耗電量

最後,目前已知深色模式能節省大量能源 AMOLED 螢幕。 著重於熱門 Google 應用程式的 Android 個案研究 和 YouTube 一樣,節能模式可節省高達 60% 的電力。 下方影片將進一步說明這些個案研究,以及各應用程式的省電功能。

在作業系統中啟用深色模式

我現已介紹過深色模式為什麼對許多使用者如此重要 讓我們來看看如何支援這項功能。

Android Q 深色模式設定
Android Q 深色主題設定

支援深色模式或深色主題的作業系統 通常可在設定中的某個位置啟用。 在 macOS X 上,請前往系統偏好設定的「一般」部分,名為「外觀」 (螢幕截圖)。 在 Windows 10 中,該選單位於「顏色」部分,其中的「選擇顏色」 (螢幕截圖)。 如果是 Android Q,您可以在「Display」下方找到「深色主題」切換鈕 (螢幕截圖)。 如果是 iOS 13,你可以在「多媒體與亮度 部分 (螢幕截圖)。

prefers-color-scheme 媒體查詢

在出發前還有最後一點理論 媒體查詢 可讓作者測試及查詢使用者代理程式或顯示裝置的功能值或功能, 可以獨立執行 在 CSS @media 規則中使用這些字元,就能有條件地將樣式套用至文件。 以及各種其他情境和語言,例如 HTML 和 JavaScript 媒體查詢層級 5 推出所謂的使用者偏好媒體功能 ,可讓網站偵測使用者偏好的內容顯示方式。

prefers-color-scheme 媒體功能 如果使用者要求網頁採用淺色或深色主題。 其運作方式如下:

  • light: 表示使用者已通知系統,表示自己偏好使用淺色主題的網頁 (在淺色背景上使用深色文字)。
  • dark: 表示使用者已通知系統,表示偏好使用深色主題的網頁 (淺色文字在深色背景上)。
,瞭解如何調查及移除這項存取權。

支援深色模式

檢查瀏覽器是否支援深色模式

由於深色模式是透過媒體查詢回報,因此您可以輕鬆查看目前的瀏覽器 檢查媒體查詢「prefers-color-scheme」是否完全相符,即可支援深色模式。 請注意,我並未加入任何值,但純粹只是檢查媒體查詢是否相符。

if (window.matchMedia('(prefers-color-scheme)').media !== 'not all') {
  console.log('🎉 Dark mode is supported');
}

截至本文撰寫時間為止,prefers-color-scheme 支援電腦和行動裝置 (如適用) 自 Chrome 和 Edge 推出 76 版,Firefox 67 以上版本 和 Safari。 如果使用其他瀏覽器,建議您前往「我可以使用支援表格」一文。

在要求期間瞭解使用者的偏好

Sec-CH-Prefers-Color-Scheme 用戶端提示標題 可讓網站在收到要求時,選擇取得使用者的色彩配置偏好設定。 讓伺服器內嵌正確的 CSS,避免顏色主題閃爍。

深色模式的實際運作情形

最後,來看看支援深色模式的實際運作方式。 就像 Highlander 一樣, 在深色模式中,只能套用深色或淺色模式,但兩者不能同時套用! 為什麼我這麼提到?因為這應該會影響載入策略。 請勿強制要求使用者在重要的轉譯路徑下載 CSS 也就是他們目前不使用的模式 為了加快載入速度,我將範例應用程式拆分為 CSS ,為實際運作中的 延遲不重要的 CSS 分為三個部分:

  • style.css,包含在網站上通用的一般規則。
  • dark.css,只包含深色模式所需的規則。
  • light.css,只包含淺色模式所需的規則。

載入策略

後者:light.cssdark.css 會透過 <link media> 查詢有條件地載入。 一開始 並非所有瀏覽器都支援 prefers-color-scheme (可透過上方模式偵測)。 我必須載入預設的 light.css 檔案,以動態方式處理這項作業 透過在減號內嵌指令碼中,有條件插入 <link rel="stylesheet"> 元素的操作 (可選擇輕度淺色,我也能將預設備用體驗設為深色)。 為了避免閃爍的內容, 在 light.css 載入之前,我會隱藏網頁內容。

<script>
  // If `prefers-color-scheme` is not supported, fall back to light mode.
  // In this case, light.css will be downloaded with `highest` priority.
  if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') {
    document.documentElement.style.display = 'none';
    document.head.insertAdjacentHTML(
      'beforeend',
      '<link rel="stylesheet" href="/light.css" onload="document.documentElement.style.display = \'\'">',
    );
  }
</script>
<!--
  Conditionally either load the light or the dark stylesheet. The matching file
  will be downloaded with `highest`, the non-matching file with `lowest`
  priority. If the browser doesn't support `prefers-color-scheme`, the media
  query is unknown and the files are downloaded with `lowest` priority (but
  above I already force `highest` priority for my default light experience).
-->
<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)" />
<link
  rel="stylesheet"
  href="/light.css"
  media="(prefers-color-scheme: light)"
/>
<!-- The main stylesheet -->
<link rel="stylesheet" href="/style.css" />

樣式表架構

我善用 CSS 變數 讓通用的 style.css 更加廣泛 自訂淺色或深色模式的所有作業,都會在另外兩個檔案 (dark.csslight.css) 中進行。 下方摘錄了實際風格,但這足以傳達整體概念。 我宣告 -⁠-⁠color-⁠-⁠background-color 兩個變數 建立暗黑淺色深色基準主題。

/* light.css: 👉 dark-on-light */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
}
/* dark.css: 👉 light-on-dark */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
}

style.css 中,我會在 body { … } 規則中使用這些變數。 這些是 :root CSS pseudo-class: HTML 中代表 <html> 元素的選取器 與選取器 html 相同,但明確性是 順序較高,因此會逐步下降,因此我將需要宣告全域 CSS 變數。

/* style.css */
:root {
  color-scheme: light dark;
}

body {
  color: var(--color);
  background-color: var(--background-color);
}

在上述程式碼範例中,您可能已經注意到 color-scheme敬上 並以空格分隔的值為 light dark

讓瀏覽器知道我的應用程式支援哪些色彩主題 可讓您啟用使用者代理程式樣式表的特殊變化版本 例如讓瀏覽器顯示表單欄位 搭配深色背景和淺色文字、調整捲軸 或啟用可感知主題的醒目顯示顏色。 如要指定 color-scheme 的確切詳細資料,請前往 CSS 顏色調整模組層級 1

其他一切,只要定義 CSS 變數即可 決定他們是否使用我們的服務 使用深色模式時,巧妙整理樣式可帶來許多助益。 舉例來說,請考慮呼叫變數,而非 -⁠-⁠highlight-yellow -⁠-⁠accent-color,如同「黃色」但在深色模式中,顯然可能不會是黃色,反之亦然。 以下舉例說明我在範例中使用的其他變數。

/* dark.css */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
  --link-color: rgb(0, 188, 212);
  --main-headline-color: rgb(233, 30, 99);
  --accent-background-color: rgb(0, 188, 212);
  --accent-color: rgb(5, 5, 5);
}
/* light.css */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
  --link-color: rgb(0, 0, 238);
  --main-headline-color: rgb(0, 0, 192);
  --accent-background-color: rgb(0, 0, 238);
  --accent-color: rgb(250, 250, 250);
}

完整範例

在下方嵌入的 Glitch 中, 您會看到將上述概念實際應用的完整範例。 嘗試在特定作業系統設定中切換深色模式 查看網頁的反應

正在載入影響

使用這個範例玩遊戲時,可以看到 為何我透過媒體查詢載入dark.csslight.css。 請嘗試切換深色模式,並重新載入頁面: 系統仍會載入目前不相符的特定樣式表,但優先順序最低的 ,讓它們不會與網站目前所需的資源競爭。

,瞭解如何調查及移除這項存取權。
顯示網路載入圖表,顯示在淺色模式下,CSS 會以最低優先順序載入深色模式
以淺色模式的網站載入深色模式的 CSS,且優先順序最低。
,瞭解如何調查及移除這項存取權。
顯示網路載入圖表,顯示在深色模式下,CSS 會以最低優先順序載入淺色模式
採用深色模式的網站會載入低優先順序的 CSS。
,瞭解如何調查及移除這項存取權。
顯示網路載入圖表,顯示在預設淺色模式下,CSS 會以最低優先順序載入深色模式
如果網站在不支援 prefers-color-scheme 的瀏覽器上,預設淺色模式中的網站就會以最低優先順序載入深色模式 CSS。

回應深色模式的變更

如同其他媒體查詢變更,您也可以透過 JavaScript 訂閱深色模式變更。 舉例來說,您可以使用這個程式碼 網站小圖示 或變更 <meta name="theme-color">敬上 決定 Chrome 網址列的顏色。 上方的完整範例說明瞭實際運作方式。 如要查看主題顏色和網站小圖示變更,請開啟 在另一個分頁中查看示範

const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
darkModeMediaQuery.addEventListener('change', (e) => {
  const darkModeOn = e.matches;
  console.log(`Dark mode is ${darkModeOn ? '🌒 on' : '☀️ off'}.`);
});

如果你使用 Chromium 93 和 Safari 15,可以根據 使用 meta 佈景主題色彩元素的 media 屬性的媒體查詢。 並選出第一個相符的結果例如,您可以用某個顏色 以及淺色模式和深色模式在本文撰寫期間,您無法 在資訊清單中定義這些要求請參閱 w3c/manifest#975 GitHub 問題

<meta
  name="theme-color"
  media="(prefers-color-scheme: light)"
  content="white"
/>
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black" />

偵錯及測試深色模式

在開發人員工具中模擬 prefers-color-scheme

切換整個作業系統的色彩配置 可能會讓人迅速感到厭煩 因此 Chrome 開發人員工具現在可以模擬使用者偏好的色彩配置 以限制目前可見的分頁。 開啟指令選單,開始輸入 Rendering 並執行 Show Rendering 指令,然後變更「Emulate CSS media featurerefers-color-scheme」選項。

「Emulate CSS media featurerefers-color-scheme」的螢幕截圖這個選項位於 Chrome 開發人員工具的「轉譯」分頁中

使用 Puppeteer 拍攝的「prefers-color-scheme」螢幕截圖

Puppeteer 是 Node.js 程式庫 提供了用來控制 Chrome 或 Chromium 的高階 API 開發人員工具通訊協定。 透過 dark-mode-screenshot Puppeteer 指令碼可用來製作深色和淺色模式的頁面螢幕截圖。 您可以一次性執行這個指令碼,也可以將其用於 持續整合 (CI) 測試套件。

npx dark-mode-screenshot --url https://googlechromelabs.github.io/dark-mode-toggle/demo/ --output screenshot --fullPage --pause 750

深色模式最佳做法

避免使用純白色

您可能已註意到,我不會使用純白色。 相反地,為了避免周圍黑暗內容出現發光和出血, 我會選擇較深的白色。類似「rgb(250, 250, 250)」的內容都能正常運作。

重新為攝影圖像上色及調暗

如果比較下方兩張螢幕截圖,會發現核心主題有變化 從黑暗黑暗,但主頁橫幅也略有不同。 我的使用者研究 已顯示絕大多數的受訪使用者 開啟深色模式時,建議較不會鮮豔搶眼的圖片。 這就是所謂的「重新上色」

主頁橫幅在深色模式中會稍微調暗。
主頁橫幅在深色模式中會稍微調暗。
,瞭解如何調查及移除這項存取權。
在淺色模式下的一般主頁橫幅。
在淺色模式下的一般主頁橫幅。

你可以使用 CSS 濾鏡將我的圖片重新上色。 我使用 CSS 選取器,符合網址中含有 .svg 的所有圖片。 讓我能以不同方式改變向量圖形 (圖示) 的顏色 。如需更多相關資訊,請參閱下一個段落。 請注意,我再次使用 CSS 變數 之後就能彈性地變更濾網

只有在深色模式中才需要重新上色,也就是說,啟用 dark.css 時。 「light.css」中沒有對應的規則。

/* dark.css */
--image-filter: grayscale(50%);

img:not([src*='.svg']) {
  filter: var(--image-filter);
}

使用 JavaScript 自訂深色模式重新調色強度

每個人的深色模式不盡相同,且使用者的需求各不相同。 採用上述的重新設定顏色方法後, 我也可以輕鬆將灰階濃度設為使用者喜好 透過 JavaScript 變更 我也可以設定 0% 的值,完全停用重新上色功能。 請注意,document.documentElement 提供文件根元素的參照。 也就是 我可以透過 :root CSS 虛擬類別

const filter = 'grayscale(70%)';
document.documentElement.style.setProperty('--image-filter', value);

反轉向量圖形和圖示

向量圖形 (在本案例中,我是指透過 <img> 元素參照的圖示),我 使用不同的重新設定顏色方式。 研究 但對於相片的反轉功能 大多數圖示的效果都非常出色 我再次使用 CSS 變數來計算反轉金額 處於一般狀態且處於 :hover 狀態

系統會在深色模式中反轉圖示。
系統會在深色模式中反轉圖示。
,瞭解如何調查及移除這項存取權。
淺色模式中的一般圖示。
淺色模式中的一般圖示。

再次提醒,我只會反轉 dark.css 中的圖示,而不在 light.css 中反轉圖示,以及 :hover 在兩種情況下會以不同的反轉強度來設定圖示 會視使用者選取的模式而定。

/* dark.css */
--icon-filter: invert(100%);
--icon-filter_hover: invert(40%);

img[src*='.svg'] {
  filter: var(--icon-filter);
}
/* light.css */
--icon-filter_hover: invert(60%);
/* style.css */
img[src*='.svg']:hover {
  filter: var(--icon-filter_hover);
}

使用 currentColor 建立內嵌 SVG

針對內嵌可擴充向量圖形圖片,請勿使用反轉篩選器, 可以使用 currentColor 代表元素 color 屬性值的 CSS 關鍵字。 這樣就能在預設不會接收到的屬性上使用 color 值。 方便使用 currentColor 做為 SVG 的值 fillstroke 屬性, 則會從色彩屬性值沿用而來。 更棒的是,這也適用於 <svg><use href="…"></svg>、 例如可以有個別的資源 且 currentColor 仍會在結構定義中套用。 請注意,這項功能僅適用於內嵌<use href="…"> SVG。 而非 SVG。src透過 CSS 參照為圖片的 SVG。 您可以在下方的示範中查看套用狀態。

<!-- Some inline SVG -->
<svg xmlns="http://www.w3.org/2000/svg"
    stroke="currentColor"
>
  […]
</svg>

在不同模式之間順暢轉換

從深色模式切換為淺色模式 (反之亦然) 都可以透過 colorbackground-color 都達到 CSS 屬性。 建立動畫就和為兩個屬性宣告兩個 transition 一樣簡單。 以下範例呈現了整體概念,您可以實際運用 demo」。

body {
  --duration: 0.5s;
  --timing: ease;

  color: var(--color);
  background-color: var(--background-color);

  transition: color var(--duration) var(--timing), background-color var(
        --duration
      ) var(--timing);
}

深色模式的藝術方向

雖然基於載入效能的原因,通常建議單獨使用 prefers-color-scheme <link> 元素的 media 屬性 (而非樣式表內嵌) 在某些情況下,您可能需要直接在 HTML 程式碼中使用 prefers-color-scheme。 這時藝術方向就是個例子。 網路上的藝術方向一般與網頁的整體視覺外觀 以及視覺呈現方式 刺激情緒和對比度,展現心理氛圍,吸引目標對象。

在深色模式下,設計人員可以自行判斷特定模式中的最佳影像品質 以及將圖片重新調色是否不夠理想。 搭配 <picture> 元素使用時,可依據 media 屬性讓要顯示的圖片 <source>。 在下方範例中,我針對深色模式顯示西半球,而淺色模式的東半球 或在沒有偏好的情況下,其他情況下會預設為東半球。 當然,此處僅供參考。 切換裝置上的深色模式即可看到差異。

<picture>
  <source srcset="western.webp" media="(prefers-color-scheme: dark)" />
  <source srcset="eastern.webp" media="(prefers-color-scheme: light)" />
  <img src="eastern.webp" />
</picture>

深色模式,但新增選擇不採用

如上方「為什麼要使用深色模式」一節所述, 對多數使用者來說,深色模式是美學的選擇。 因此,有些使用者可能會想採用作業系統使用者介面 但仍然希望以之前的方式瀏覽網頁 良好的模式是一開始會遵循瀏覽器 prefers-color-scheme,但可選擇允許使用者覆寫系統層級設定。

<dark-mode-toggle> 自訂元素

當然您也可以自行建立程式碼 我為這個目的建立了現成自訂元素 (網頁元件)。 名稱為 <dark-mode-toggle> 並會顯示一個切換鈕 (深色模式:開啟/關閉) 可讓您完全自訂網頁的主題切換器 (主題:淺色/深色)。 以下示範說明元素的實際運作情形 (我也會隨心所欲地吸取 其他 範例 上述內容)。

<dark-mode-toggle
  legend="Theme Switcher"
  appearance="switch"
  dark="Dark"
  light="Light"
  remember="Remember this"
></dark-mode-toggle>
敬上
在淺色模式下切換深色模式
淺色模式的 <dark-mode-toggle>
,瞭解如何調查及移除這項存取權。
在淺色模式下切換深色模式
深色模式的 <dark-mode-toggle>

在下方的示範中,請嘗試點選或輕觸右上角的深色模式控制項。 如果您勾選了第三和第四個控制項中的核取方塊,請查看所選模式的選擇方式 即使重新載入網頁,系統仍會記錄下來。 讓訪客維持其作業系統的深色模式 但仍可在淺色模式下盡情瀏覽網站,反之亦然

結論

使用和支援深色模式既有趣,還能開啟新的設計途徑。 有些訪客無法順利處理網站,這可能就是 並且維持良好的使用體驗 一些陷阱 而且一定要經過仔細的測試 但深色模式向來是展現您所有使用者的好機會 這篇文章中提到的最佳做法,以及 <dark-mode-toggle> 自訂元素 讓你有信心能夠打造出色的深色模式體驗。 透過 Twitter 告訴我你製作的內容,以及這篇貼文是否實用 或是提出改善建議 感謝閱讀!🌒

prefers-color-scheme 媒體查詢的資源:

color-scheme 中繼標記和 CSS 屬性的資源:

一般深色模式連結:

這篇文章的背景研究文章:

特別銘謝

prefers-color-scheme 媒體功能、color-scheme CSS 屬性 和相關中繼標記是 👏? Rune Lillesveen 的實作工作。 Rune 也是 CSS 色彩調整模組層級 1 規格的共同編輯工具。 我要 🙏? 感謝 Lukasz Zbylut 敬上 Rowan MerewoodChirag Desai、 和 Rob Dodson 瞭解這篇文章 載入策略Jake Archibald 的大腦。 Emilio Cobos Álvarez 指向正確的 prefers-color-scheme 偵測方法。 使用參照 SVG 和 currentColor 的提示來自 Timothy Hatcher。 最後,我要感謝許多匿名使用者參加各種使用者研究 有助於改善本文所述的建議。 主頁橫幅由 Nathan Anderson 提供。