LoginSignup
24
21

More than 1 year has passed since last update.

あんまり手間をかけない、なんちゃってダークモードUIの作り方

Last updated at Posted at 2021-04-19

これは何

  • Dark ModeのUIを「厳密ではないけど手間をかけずにそれっぽく作る」ためのTipsを書いた記事です
  • あくまでなんちゃってです、ご了承ください
    • 本当は手を入れないといけない箇所が色々あります
    • 暗い背景にあわせてメインカラーの明度や彩度を調整するとか
    • Light Modeでbox-shadowを使ってelevationを表現している箇所は、box-shadowをやめてsurfaceの色の違いelevationを表現するとか

完成品

GitHub Pagesで公開しました。
ページを開いた上で、システムの設定でLightとDarkを入れ替えて見てください。
リロード無しでUIが切り替わります。

スクリーンショットも載せておきます。

Light Mode Dark Mode
白い背景に黒い文字の画面 黒い背景に白い文字の画面

おおまかな仕組み

@media (prefers-color-scheme: dark)とCSS Custom properties(CSS変数)を組み合わせます。

@media (prefers-color-scheme: dark)はメディアクエリの一種で、ユーザーがシステム設定でLight ModeをDark Modeのどちらを選んでいるかを判別できます。
そして、予めCSS変数で定義しておいた色だけを使ってスタイリングをすれば1つのコードでLightとDarkどちらのUIも組めるようになる、という仕組みです。

実際のコード

全てのコードはGitHubをご覧ください。
この記事の中ではCSSだけにフォーカスします。

CSS変数で使う色をひとしきり定義する

:root要素の中でCSS変数を定義すると、ページ内のどこでも使えるようになります。
通常用(=Light Mode)のパレットと、Dark Mode用のパレットをそれぞれ定義しています。

style.css
:root {
  --text-high-emphasis: rgba(0 0 0 / 0.87);
  --text-medium-emphasis: rgba(0 0 0 / 0.6);
  --text-on-primary: rgba(255 255 255 / 0.87);
  --primary: #0d47a1;
  --background: #f6f6f6;
  --surface: #fff;
}

@media (prefers-color-scheme: dark) {
  :root {
    --text-high-emphasis: rgba(255 255 255 / 0.87);
    --text-medium-emphasis: rgba(255 255 255 / 0.6);
    --text-on-primary: rgba(0 0 0 / 0.87);
    --primary: #ffca28;
    --background: #212121;
    --surface: #2f2f2f;
  }
}

Sassの変数ではダメ?

スタイルを組む上ではSassの変数の方が馴染み深い方も多いかもしれませんが、それではNGです。
このようにコードを書いたとして、Light Mode用の色が適用されることはありません。

:root {
  $text-high-emphasis: rgba(0 0 0 / 0.87) !global;
  $text-medium-emphasis: rgba(0 0 0 / 0.6) !global;
  $text-on-primary: rgba(255 255 255 / 0.87) !global;
  $primary: #0d47a1 !global;
  $background: #f6f6f6 !global;
  $surface: #fff !global;

  @media (prefers-color-scheme: dark) {
    $text-high-emphasis: rgba(255 255 255 / 0.87) !global;
    $text-medium-emphasis: rgba(255 255 255 / 0.6) !global;
    $text-on-primary: rgba(0 0 0 / 0.87) !global;
    $primary: #ffca28 !global;
    $background: #212121 !global;
    $surface: #2f2f2f !global
  }
}

Sassの変数はあくまで「Sass上では同じ値として繰り返し使える」存在です。
CSSに変換された後は動的に値を変更できないため、後に書いてある(prefers-color-scheme: dark)のルールしか適用されません。
(もちろん、darkを先、lightを後と順番を変えて書いたらlightのルールしか適用されません。)

定義したCSS変数でスタイルを組む

あとは、定義したCSS変数を使ってコードを書いていくだけです。
普通のCSSを書くのとほとんど変わりません。

実際のコードから一部抜粋
html {
  background-color: var(--background);
  color: var(--text-high-emphasis);
}

.main {
  background-color: var(--surface);
  border-radius: 16px;
  padding: 32px;
  width: min(640px, 100%);
}

.note {
  color: var(--text-medium-emphasis);
  font-size: 12px;
  margin-top: 16px;
}

.button {
  background-color: var(--primary);
  border-radius: 8px;
  color: var(--text-on-primary);
  font-size: 18px;
  font-weight: 700;
  margin-top: 32px;
  padding: 12px 16px;
}

var(--somecolor)の書式になっている箇所がCSS変数を用いている箇所です。
Dark Modeのためだけのコードは1行も書いていません。

カラーシステムの設計

ちなみに本筋からは外れますが、色の設計をするときはMaterial Designのcolor systemを参考にすると分かりやすいと思います。

  • 背景色(Background)
  • 要素の表面の色(Surface)
  • メインの色(Primary)

といったように考えることで、そもそも秩序ある配色でプロダクトを作れるようになります。
これはCSSだけの話ではなく、UIのモックアップ作成のときから考えておけると良い項目です。

まとめ

  • @media (prefers-color-scheme: dark)とCSS Custom properties(CSS変数)を組み合わせる
    • Sassの変数ではNG
  • 定義した色を用いてスタイリングをする
    • Material Designのcolor systemの考え方を取り入れると分かりやすい
24
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
21