ダークモードの実装

追記(2019/05/22): Firefox 67に対応したので内容を変更しました。

(この記事はMacOS Mojave〜を対象とした話になります)

ダークモード

Mac OSのMojave(10.14以降)には、ダークモード(Dark Mode)が搭載されています。
配色を暗めにして、ユーザーの目の負担を抑えたりする機能です。
従来の画面は、ライトモード(Light Mode)として区別されています。

多くのネイティブアプリで対応が進んでいますが、最近では一部のWebページも対応しています。
ユーザーの操作などに応じて、CSSのスタイルを切り替えるというシンプルなものです。

ボタンでの実装

多くのページでは、トグル式、またはラジオボタンを用意して対処しています。
また、localstorageに状態を保存するページもあります。

How I added Dark Mode to my website

上記ページでは、.darkクラスの付け外しで対応しています。

prefers-color-schemeでの実装

※この項目は、策定中の仕様について触れています。記述内容から変更があるかもしれません。

prefers-color-schemeは、Media Queries Level 5で策定中のメディアクエリです。
ユーザーがライトモード、ダークモードどちらの配色を指定しているのかを判定することができます。
現時点では、Safari12.1、Firefox 67以降のバージョンでのみ対応していますが、Chromeも次期バージョンで採用の予定です。

値は、no-preference(設定なし) | light | darkの3種類から指定できます。
CSS Variablesと併せて、既に一部のサイトに取り入れられているようです。

CSS
// ライトモードの時
@media (prefers-color-scheme: light) {
  :root {
    --main-bg-color: #fff;
    --main-text-color: #000;
  }
}

// ダークモードの時
@media (prefers-color-scheme: dark) {
  :root {
    --main-bg-color: #1e1e1e;
    --main-text-color: #fff;
  }
}

body {
  background-color: var(--main-bg-color);
  color: var(--main-text-color);
}

草案
"Can I use..." より対応バージョン
近づくダークモード対応の足音 | フロントエンドBlog | ミツエーリンクス
prefers-color-scheme を用いた Dark Mode 対応と User Preference Media Features | blog.jxck.io

matchmediaで分岐させる

prefers-color-schemeはメディアクエリなので、matchmediaを用いた対応が可能です。
ダークモード時に、MediaQueryListオブジェクトのmatchesがtrueになるので、そちらで判定します。

JavaScript
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

また、イベントハンドラを登録することもできます。

JavaScript
window
  .matchMedia('(prefers-color-scheme: dark)')
    .addListener(({ matches }) => {
      if (matches) {
        // ダークモードの時の処理
      }
    });

ライトモードとダークモードでコンテンツを出し分ける、というのをやりました。
あくまでユーザー支援の位置付けなので、演出として用いるのはどうかと思いますが…。

prefers-color-schemeを用いて昼と夜を切り替えるアニメーション
雲のイラストはこちらから拝借しました: https://codepen.io/Mark_Bowley/pen/xEbuI

注意点

単に配色を置き換えるだけでなく、様々な注意事項・懸念点があります。

ダークモードの背景色には、#282c2f#1e1e1eなどの黒に近いグレーが搭載されることが多いです。
#000と文字#fffはコントラストが高く、あまり採用されないようです。

文字や背景にピュアブラックを使ってはいけない理由 | UX MILK
(元記事: Why You Should Never Use Pure Black for Text or Backgrounds)

文字

背景色が変わると、文字の印象も異なります。
下記リンク先のStuff & Nonsenseは、配色を変えるだけでなく、文章のline-heightword-spacingも調整しています。

Redesigning your product and website for dark mode — Stuff & Nonsense

画像

その実態はCSSいじりということで、画像へのフォローも必要になってきます。
特に白地の背景だと辛くなってしまうので、透過pngや、SVGを検討した方が良いかもしれません。
一応、picture要素のメディアクエリで画像を出し分けることは可能です。

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

box-shadow

CSS
@media (prefers-color-scheme: dark) {
  * {
    box-shadow: none !important;
  }
}

その他

WebKitのInspectorがダークモードに対応した時の記事が参考になるかもしれません。

終わり

暗めの配色を望むユーザーにとっては最適なダークモードですが、その実装には癖があります。
導入の際にはデザイナーとの連携や、CSSで対応できない箇所のフォローが必要になってきます。