Dark mode with web design

Paul Li
9 min readJun 24, 2019

--

Dark mode with web design

Introduction

Dark mode 是近兩年來蠻熱門的議題, 講白了, 它就是一種 theme, 一種依照當前環境做區分的 theme, 更是一種讓服務貼近生活的態度.

如果你的服務不支援 dark mode 會怎樣 ?

老實說一點都不會怎樣, 只是…在特定的環境下, 會讓 user 在使用上會感到吃力且疲倦, 試想 facebook 好了, 它的基調大多是白色背景單配黑色的文字, 在燈光明亮的狀態下瀏覽或許感到舒適, 但是, 如果在昏暗亦或是睡前躺在床上使用時, 眼睛便會因為對比的銳利而感到疲憊, 我想…這都不是我們想提供給 user 的感受.

所以, 除了 OS 提供 dark mode 的功能外, 服務所呈現的 web content 是否也能提供 dark mode 呢 ? 這便是我們今天想要討論的議題.

最新的 macOS 在 System Preference 裏提供了 light / dark mode 供 user 選擇, 大部分的 UI 也會依照 user 的選擇做出相對應的變化, 除此之外, 很多應用程式, 比方說 Chrome, 亦提供了 dark mode 這樣的 theme 讓 user 有更多的選擇, 顯示說 dark mode 不僅僅是一種潮流, 更是一個良好的產品態度的彰顯.

在 WWDC 2019 便有一環講到如何讓 web content support dark mode (iOS 13). 而且 Android Q 亦有 support dark theme.

- Support Dark mode in Your Web Content
- Android Q with Dark theme

Nothing but CSS

如同上段所述, dark mode 就是一種 theme, 也就是說先決條件必須要有一套完整的 design language, 一但有了明確且完整的 design language 後, 剩下的事情就相對簡單許多.

如下所示, 這是筆者拿來示範用的 demo site (light mode).

demo site — light mode (link)

我們的目標很明確, 即設計一 CSS dark mode 的 theme, 讓 web page 可以自動的依據當前系統設定, 自動將 web content 轉換成 dark mode

demo site — dark mode (link)

在 CSS 的設定上, 其實非常的簡單, 只要明確在 root 定義 color-scheme, 其實便已完成了

<style>:root {
color-scheme: light dark;
}
</style>

CSS Color Adjustment Module Level 1

透過該屬性的設置, 便可以快速的設定當前 web page 的 color scheme, 主色系便會自動被 apply, 比方說 background color 和 text color

方便歸方便, 不過很多時候系統預設的 color scheme 可能與服務的 design language 不盡相同, 因此更細緻化的呈現是有必要的. 那麼…除了 color-scheme 的設置外, 我們還能有什麼樣的手段呢 ?

可以透過 CSS media query 的條件設置, 來 overwrite 一些相關屬性, 其運作原理很簡單, 只要當前的 OS 設置為 dark mode, 便會掉進去我們預期的設定

<style>header {
background-color: #fff;
color: #000;
}
@media (prefers-color-scheme: dark) {
header {
background-color: #000;
color: #fff;
}
}
</style>

如此, developers 便可以根據不同的 module 做出更為細緻且出色的表現, 如果搭配 CSS var() 的使用, 更可以讓這些 color scheme 更好管理且套用.

讓我們把上述的 CSS 再改寫一下

<style>:root {
--header-background-color: #fff;
--header-text-color: #000;
}
header {
background-color: var(--header-background-color);
color: var(--header-text-color);
}
@media (prefers-color-scheme: dark) {
:root {
--header-background-color: #000;
--header-text-color: #fff;
}
}
</style>

瞧出箇中翹楚了嗎 ? 透過 CSS, 便能輕輕鬆鬆讓你的服務也能 support dark mode. 讓我們看看在 macOS 以及 iOS 13 上面的表現

macOS Mojave & safari version 12.1.1
iOS 13 & mobile safari

What else ?

WWDC 2019 除了有揭露 dark mode 於 CSS 的設置方法外, 另外還有其他設置方法, 基本上只要有 support media query 語法的 html tag, 應該都可以吃得到 OS dark mode 模式.

<picture>
<source srcset="mojave-night.jpg"media="prefers-color-scheme: dark">
<img src="mojave-day.jpg">
</picture>

如上所示, developer 便可以根據當前 OS 設置來做不同的 image 呈現, 讓 dark mode 的整體支援更加完善.

看了以上介紹, 如果對 dark mode 有興趣的朋友, 只要你的 macOS 為 Mojave & safari version 12.1.1 以上, 便可以依照上述步驟來感受 dark mode 帶來的全新感受.

Appearance tracking

完成 dark mode 的設置後,追蹤 user 的使用情況亦是 frontend 需要特別注意的一個重要環節,由於 server side 無法取得當前 OS 的 appearance status,這表示說 i13n 的追蹤還是得由 client 來進行發動。

一般的頁面可以透過上段所提到的 <picture /> 再搭配 1pixel image 的方式來進行 beacon fire。

<picture>
<source srcset="beacon?appearance=dark" media="prefers-color-scheme: dark">
<img src="beacon?appearance=light">
</picture>

如此便可以快速的取得 appearance usage

不過在 AMP 類型的 web page,這樣的設置法會有錯誤,這是因為 AMP 下 <img /> 是不 allow 的 (需用 <amp-img /> 替代),所以如果想要在 AMP 下追蹤使用情況的話,就必須要額外加工,作法基本上和 <picture /> 大同小異

<style>:root {
--al: block;
--ad: none;
}
[class|="appearance"] {
position: fixed;
left: 0;
top: 0;
width: 1px;
height: 0px;
display: none;
}
.appearance-tracker-light {
display: var(--al);
}
.appearance-tracker-dark {
display: var(--ad);
}
@media (prefers-color-scheme: dark) {
:root {
--al: none;
--ad: block;
}
}
</style>
<div class="appearance-tracker-dark">
<amp-img src="beacon?appearance=dark" width="1" height="1"></amp-img>
</div>
<div class="appearance-tracker-light">
<amp-img src="beacon?appearance=light" width="1" height="1"></amp-img>
</div>

如上所示,透過 AMP runtime 的特性 (in viewport 且 display 不為 none 才會發動 image fetch) 再加上 CSS prefers-color-scheme: dark 的變數配置,隨著 OS appearance 的差異讓相對應得 <amp-img /> 動態呈現在 viewport 中,彈指之間便可以完成 AMP appearance beacon 發送,目前 Yahoo!奇摩拍賣 首頁便是利用這樣的方式來進行 data collection。

有興趣的朋友如果有這類需求的話,不妨嘗試看看。

Detect Dark mode with JavaScript

除了上述的方法外,其實也可以透過一個古老的 Web API — matchMedia 來偵測當前環境是否有支援 dark mode。

if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// dark mode
}

有兩上述兩種方式,相信對於 developer 來說可以更多元的來決定以及應用 dark mode。

Reference

--

--

Paul Li
Paul Li

Written by Paul Li

Paul is the lead programmer of the AMP project at Yahoo Taiwan and is always eager for modern web technologies. He is also focusing on UX for vivid user flow.

No responses yet