ダークモードを実装するときに考えること・気をつけること

はじめに

先日当ブログにてダークモードを実装しました。

実装の内容はZennにて記事化しましたが、ここでは実装の過程で学んだ「ダークモードを実装するときに考えること・気をつけること」をメモしておきます。

なお、ここではデザインの観点での言及は行いません。

1. ユーザーにテーマ切り替えのUIを提供するか考える

ダークモードを実装するうえで、ここが一番の分岐点になります。

UIを提供する場合

  • 切り替え用のトグルやセレクトボックスの実装
  • 切り替え状態に応じたテーマの変更
  • ユーザーの選択したテーマの永続化(storageやサーバーへの保存)

など考慮事項が増え、実装の負荷も比較的高くなります。

UIを提供せず、ユーザーのOS設定に合わせる場合はCSSの prefers-color-scheme メディアクエリに応じてスタイルを切り替えるだけ実装が完了します。

body {
  back-ground-color: #eee;
  color: black;
}

@media (prefers-color-scheme: dark) {
  body {
    back-ground-color: #333;
    color: white;
  }
}

現状、ダークモードに対応しているWebサイトでは明示的な切り替えUIを持たず、OS設定に応じた切り替えを行っていることがほとんどだと思います。(筆者の観測した範囲)

しかしJSライブラリの公式サイトやフロントエンド界隈の技術ブログなどでは、切り替えUIを提供している例も多く見かけます。当ブログも実際に切り替えのUIを実装しました。

2. color-scheme の設定を行う

color-scheme を利用すると「Webページがどのテーマをサポートしているか」をサイト側からユーザーに示すことができます。

これを正しく設定すると、ブラウザのスクロールバーやinput要素のUIがテーマに沿った配色で表示されます。

color-scheme を指定する方法は2つあります。

  • CSSプロパティ color-schme
  • HTMLのmeta要素 <meta type="color-scheme />

詳しい説明はすでによくまとまっている記事があるため、そちらをご参照ください。

https://zenn.dev/uhyo/articles/css-color-adjustment-1

https://hail2u.net/blog/meta-name-color-scheme.html

このブログではダークテーマ選択時には body 要素に sytle=”color-scheme: dark が指定されるようになっています。実際にテーマを切り替えてスクロールバーの見た目が変わっているか確かめてみてください。

3. 選択されたテーマをどこに保存するか考える

ユーザーにテーマ切り替えUIを提供する場合、ユーザーが選択したテーマはサイト内をページ遷移した際にもそのまま引き継がれてほしいはずです。そうでないとページを切り替えるごとにいちいちテーマを切り替えねばならず不便ですよね。

そのため、ユーザーが選択したテーマの情報をどこかに保存しておく必要があります。

ここではおおよそ3つの保存先が考えられます。

  • A. サーバ(DB)に保存
  • B. ブラウザのLocalStorageに保存
  • C. ブラウザのSessionStorageに保存

A. サーバ(DB)に保存

例えばGitHubのようにログイン機能があるWebサービスならサーバ(DB)に各ユーザーのテーマ選択を保存することができます。

その選択状態を元にhtmlを返せば後述するちらつきの問題も防止できます。

しかし、フロントエンドでの制御とバックエンドへのリクエストをどちらも実装する必要があるため負荷は大きくなると考えられます。

B. ブラウザのLocalStorageに保存

ログイン機能を持たない一般的なWebサイトであれば基本的にクライアント(ブラウザ)で保存する必要があります。

LocalStorageに保存するとユーザーがブラウザを閉じたあとも選択してテーマの情報が残り続けます。

そのためユーザーが再度訪問した際にも、前回のテーマ選択が引き継がれていることになります。

ユーザーがサイトに頻繁に訪れる場合、この仕組みはユーザーにとって好ましいでしょう。

一方で前回の訪問から期間が空いた後にサイトを訪れたユーザーは、前回のテーマ選択を覚えておらず、OS設定と違う見た目に違和感を抱く可能性があります。

C. ブラウザのSessionStorageに保存

SessionStorageはLocalStorageと同様にブラウザ側に保存されますが、ブラウザを閉じると保存された情報が消えるという特徴があります。

そのためユーザーがサイトを閉じた後にSessionStorageに保存されたテーマ選択情報は消え、次回サイトを訪れた際にはOS設定に応じたテーマが適用されることになります。

個人ブログやポートフォリオサイトなど、ユーザーが頻繁に訪れることがないサイトであればSessionStorageを利用することで、ユーザーにとって好ましい状態を保つことができるでしょう。

4.チラつきを防止する

ブラウザでテーマ選択状態を保存している場合、スクリプトでダークモードの判定を行うより先に初回レンダリングが実行されてしまうため、画面が一瞬チラついてしまいます。

例えば

  • OS設定はlight
  • ユーザーはDarkを選択中

の場合、スクリプトにより「ユーザーがDarkを選択している」という情報がセットされる前にページがレンダリングされ、一瞬ライトモードでページが表示されてしまいます。

その後すぐにDarkモードに切り替わるわけですが、この一瞬のチラつきはユーザーにとって好ましいものではないでしょう。

解決策としては以下の二つが挙げられます

  • 1.head内のインラインScriptで切り替えをおこなう(レンダリング前)
  • 2.サーバー側で生成済みのhtmlを返す

参考記事

https://azukiazusa.dev/blog/what-to-do-when-tailwindcss-is-momentarily-displayed-in-light-mode-in-dark-mode/

まとめ

以上、ざっくりではありますがダークモードを実装する際に考えること・気をつけることをまとめてみました。

今後ダークモードを実装する際、誰かの参考になれば幸いです。