Hubert Wang

I am
Hubert Wang

Wechat Official Account
Find fun things here!

Supporting Dark Mode in Your Website Interface

Illustration from dribbble, all rights owned by Gleb Kuznetsov✈, Link

Update colors, images, and behaviors so that your website adapts automatically when Dark Mode is active.

Overview

In macOS, iPad OS, iOS, and Android, users can choose to adopt a system-wide light or dark appearance based on ambient lighting conditions or a specific schedule. The dark appearance, known as Dark Mode, implements an interface style that many apps already adopt [1]. However, I found few guidelines on how to adopt dark mode for website interface. This article is to summarize my experiences of supporting dark mode in my own blog: hubertwang.me to a hands-on guide. Yes, codes are included.

Philosophy

Content First. Don't sacrifice contents just for looking good. The core idea of adopting dark mode is to make user feel comfortable when reading in dark.

Accessibility. Ensure that your content remains comfortably legible in Dark Mode when you adjust the contrast and transparency accessibility settings [2]. Google material design has a good article to introduce accessibility in UI design [3]. Saturated colors should also be avoided as it produces optical vibrations against a dark background, which can induce eye strain [4].

Test your design in both light and dark appearances [2]. In development, you'll be surprised on how often the dark background has made the texts disappear, vice versa.

CSS Media feature: prefers-color-scheme

The prefers-color-scheme CSS media feature is used to detect if the user has requested the system use a light or dark color theme. It has 3 syntax: no-preference, light, and dark. As the syntax suggests, dark is the key for dark mode.

See the Pen DarkMode by wanghongyang (@wanghongyang)on CodePen.

Color

Android and iOS have different ideas on how to use colors.

Android suggests to use dark gray, rather than black, as the primary surface color for components in dark theme. Dark gray surfaces can express a wider range of color, elevation, and depth, because: 1) it’s easier to see shadows on gray so using dark gray surfaces can better express the logics of color, elevation, and depth; 2) reduce contrast between text and surface. The Dark Grey recommended by Material design is #121212 .

iOS doesn't care about dark grey. Apple's apps are all using the pure black #000000 as the background. This is reasonable as the OLED screen can show "real dark", making the background fade into iPhone's curved edges -- seamlessly experience.

Which one is the better choice?

I actually recommend both and used both in my own blog: hubertwang.me. Android's recommendation is suitable for desktop and pad situations, which require complex logics on elevation and depth between multiple components. Apple's recommendation is better for iPhone experience to take the full advantage of OLED screen.

DarkGrey

"Dark Grey" looks good in webpage with complex layers.

darkmode on small screen

The pure dark is the best for OLED screen.

Image

Images with a large portion of white background stands out in dark mode and burns user's eyes. An idea to avoid this is filter: invert(100%) CSS property to invert the white color to black. But your picture can look very strange as the colorful parts are also inverted. Marcin Winchary has proposed a way to invert the white part but still keep the color by applying hue-rotate(180deg) after the inverse [5].

See the Pen Image in DarkMode by wanghongyang (@wanghongyang)on CodePen.

The drawback of this method, however, is that it also inverts the black images. If an image is mosted composed of dark colors, it will be inverted to a white image burning user's eyes. To handle this, I define a class that inverts images and assign the CSS class only to the images that need inverse. The ourcome is quite satisfying: Check this blog post in both dark mode and light mode.

References for more info on dark mode

[1] Apple Developer Appkit Article, Supporting Dark Mode in Your Interface

[2] Apple Developer Human Interface Guidelines, Dark Mode

[3] Google Material Design, Accessibility

[4] Google Material Design, Dark theme

[5] Marcin Wichary, Dark theme in a day

更新网站的颜色、图片和交互来适配黑暗模式(苹果官方称“深色模式”)。当手机设置在深色浅色之间切换的时候,你的网站也可以随之自动切换。

什么是黑暗模式

在苹果生态系统和安卓系统中,用户可以选择用黑暗模式或者明亮模式(苹果官方称深色模式和浅色模式),并且模式可以根据环境亮度和白天黑夜自动切换。大部分 App 已经适配了暗夜模式 [1],比如 QQ、淘宝(上周开始在 TestFlight 上公开测试)。但是我基本没有看到过网页端适配黑暗模式的。这篇文章想探索这个领域并提供可直接使用的代码,效果可见我的博客:hubertwang.me

适配原则

内容优先。不要单纯因为黑暗模式好看就忽略掉内容的展示。引入黑夜模式的目的就是为了在黑暗中更好地展示内容。如果为了黑暗模式好看就无脑适配甚至白天也强制用黑暗模式,可能不是好的设计考量。一个反面教材是 Jellow(即刻 App 的替身版本),它不管在白天还是黑夜都强制黑暗模式,白天看 Jellow 很费眼睛。

可用性。确保在适配黑暗模式之后网站依然是可用的。黑色背景下,对比度、透明度、饱和度都可能影响网站的可用性 [2]。举个例子,高饱和度的红色在白色背景上还可以接受,但是在黑色背景上会有视觉抖动的问题,眼睛极其容易疲劳。谷歌材质化设计有一篇很好的文章分析可用性 [3],推荐阅读。

系统黑暗模式和明亮模式都应该测到 [2]。在开发中,会遇到不少在一个模式下看起来很好但是在另一个模式下不可用的情况,所以两种模式都应该测试。

CSS 媒体特性:prefers-color-scheme

prefers-color-scheme 是一个新的 css 媒体特性,用来检测用户系统使用的主题颜色。它目前为止有 3 种可能的赋值:no-preference, light, 和 dark。其中 dark 就是适配黑暗模式的选项。

See the Pen DarkMode by wanghongyang (@wanghongyang)on CodePen.

颜色

安卓和苹果对用色有不同的设计原则。

安卓推荐使用深灰色(#121212),而不是纯黑色,作为黑暗模式下文字的底色。安卓认为深灰色可以表达更广泛的色域、层的高低、和深度。具体说的话:1)阴影是表示层高低的重要信息,而灰色上才能看到阴影,黑色上是看不到阴影的;2)纯黑色与白色文字对比度过高,灰色会减弱对比度,避免眼睛疲劳。

iOS 不鸟深灰色。在所有苹果自有的 app (比如说 books, message),都使用了纯黑色作为黑暗模式的底色,并且把文字直接放在纯黑底上。从 iPhone OLED 屏幕的角度看完全合理:OLED 能显示真正的黑,使用纯黑底可以完美地模糊边框和屏幕的边界,让屏幕完全“消失”,打造无缝的视觉。

问题来了:我们应该选择使用哪个设计范式呢?

就我自己说,我在博客里都使用了:桌面和 iPad 版本使用 Android 的深灰,因为桌面版层级复杂,深灰可以区分内容块,如下图所示:

"Dark Grey" looks good in webpage with complex layers.

而在手机端,我选择使用苹果范式,充分利用手机的 OLED 屏幕。如下图所示。

darkmode on small screen

The pure dark is the best for OLED screen.

图片

有大片白色背景的图片在整屏幕黑中会特别亮眼。考虑使用 css 的滤镜属性做颜色反转。[5] 提出了一个更好的设方法:单纯颜色反转会让彩色失真,在反转后做 hue rotate 可以保留彩色。代码和效果如下:

See the Pen Image in DarkMode by wanghongyang (@wanghongyang)on CodePen.

这个方法也有它的局限性:如果图片本身就是黑色的,反转会让它变白。针对这个问题,我的处理方法是做一个专门反转照片的 class ,手动标记需要反转颜色的图片。虽然会多一些手动的操作,但是效果很好。欢迎点击文章阅读原文查看黑暗模式下的文章效果。

参考文献和扩展阅读

[1] 苹果开发者文档,支持深色模式

[2] 苹果交互设计文档,深色模式

[3] 谷歌材质化设计,可用性

[4] 谷歌材质化设计,深色模式

[5] Marcin Wichary, 一天学会黑夜模式

342
TOC
Comments
Write a Comment
  • On 2020/1/1:

    Comment from Hector Guo http://hectorguo.com/ on Wechat:

    Another straightforward way is to use `mix-blend-mode`.

    海哥的评论:『利用 mix-blend-mode 更简单粗暴』。

  • On 2020/1/9:

    Alibaba has published a good article about dark mode today: http://translate.google.com/translate?hl=en&sl=zh-CN&u=https://wemp.app/posts/f0cd0fee-b85f-493e-a7f7-4e342ba63f5c&prev=search

    阿里巴巴钉钉有一个很好的 Dark Mode 设计文章:https://wemp.app/posts/f0cd0fee-b85f-493e-a7f7-4e342ba63f5c