LINEで現役エンジニアに直接質問してみよう!登録無料

CSSでダークモードに対応したWebサイトの実装方法!「prefers-color-scheme:dark」の使い方

CSSでprefers-color-schemeを使うことで、Webページをダークモードに対応させることができます。

スマホやディスプレイは明るい部屋で使うことが今まで当たり前でした。しかし、スマホが普及したことでくらい部屋で使い人が多くなり、暗い場所でも目に優しくよく見えるページを求める需要が増えたことにより、ダークモードが登場しました。

ダークモードを使うには、CSSのprefers-color-schemeとメディアのクエリを併用します。

@media (prefers-color-scheme:dark) {
    body {
        color: #f1f1f1;
        background-color: #222;
    }
}

今後、ニーズが増えてくる可能性があります。特にエンジニアなど、情報の検索頻度の多い人には嬉しい機能です。

prefers-color-schemeとは?

prefers-color-schemeを使うと、Webサイトを見ているユーザーのPCのカラーテーマを検出することができます。prefers-color-scheme:lightとすればライトモード(通常モード)、prefers-color-scheme:darkとすればダークモードを表します。

MEMO

prefers-color-schemeはCSSプロパティではなく「メディア特性」や「メディア特性式」と呼ばれる特別な書き方で、それ自体が値を持っています。そして、その値によって特定の環境でのみ機能するCSSを書くことができます。

メディア特性については、下記の記事のようにたくさんの種類があります。

参考 メディアクエリの使用 - メディア特性mozilla

prefers-color-schemeの値

prefers-color-schemeから取れる値は3つあります。

no-preference
そもそもライトモードとかダークモードとか設定がない場合は
light
Webページ閲覧環境がライトモードになっていた場合を示します。これがMacのデフォルトです。
dark
Webページ閲覧環境がダークモードになっていた場合を示します

prefers-color-schemeの使い方(基本)

ダークモードに対応するCSSを書く方法はとっても簡単です。prefers-color-schemeの値をメディアのクエリによって判断させるだけです。

@media (prefers-color-scheme:dark) {
    body {
        color: #f1f1f1;
        background-color: #222;
    }
}

ダークモード時、@media (prefers-color-scheme:dark)で囲まれた部分が適用されます。

JavaScriptからprefers-color-schemeの値を取得して使う

prefers-color-schemeはCSSだけで使えるのではなくて、JavaScriptからも使うことができます。

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

console.log(isDarkMode);

isDarkModetrueなだダークモードで、falseならそれ以外です。
これを応用すれば、ダークモードだったらクラスを付与して、それ以外だったら付与しないといった使い方ができ、デザインの幅が広がります。

prefers-color-schemeを実装してみた感想

実際に実装してみると分かりますが、このままただ実装するコストが高くなる可能性があります。それは下記のような理由があるからです。

  • ダークモードとライトモードの実装部分に差異が生じる
  • 2箇所の変更を忘れずに修正しなければいけない
  • CSS全体がとてつもなく長くなっていく危険性がある

ダークモードとライトモードの実装部分に差異が生じる

prefers-color-schemeを使うということは、同じパーツに対してダークモードとライトモード2種類の変更を加えなくてはいけません。

変更に変更を加えていくと、どんどんダークモード部とライトモード部の実装に差異が生じてしまうことは容易に想像が付きます。

2箇所の変更を忘れずに修正しなければいけない

font-sizemarginは共通しているとおもうので、その部分はダークモードとライトモードは揃えておきたいですよね?しかし、@media (prefers-color-scheme:dark)で分かれていると、2つの部分を忘れずに修正しなければいけません

CSS全体がとてつもなく長くなっていく危険性がある

CSSがダークモードに関する部分とライトモードに関する部分にまたがるので長くなります。

このような問題を解決する方法

このような問題にはCSSの変数をうまく使えば解決することが出来ます。簡単に管理できるようになるので試してみてください!

色の管理はCSS変数を使って簡単にする!

ダークモードに対応するCSSを書いていくと、どんどん行数が増えていきます。これでは後々色を変更しようと思った時が大変です。

そこで、CSS変数を使いましょう!CSS変数とは、下記のように色情報を変数として持っておき、いろいろな場所で値を使い回すことができる機能です。

/* 変数を定義する。`:root`内に書くとグローバル変数になる */
:root {
    --main-color: #ffffff;
    --accent-color: #2d4061;
}

/* 変数を使うには`var()`と組み合わせて使う */
p {
    background-color: var(--main-color);
    color: var(--accent-color);
}

この機能を@media (prefers-color-scheme:dark)を組み合わせて使うと、コードの行数が少なくなったり、後で変更しようと思った時、すぐに対応できるのでとても便利です。

:root {
    --main-color: #ffffff;
    --accent-color: #2d4061;
}

@media (prefers-color-scheme:dark) {
    :root {
        --main-color: #ffffff;
        --accent-color: #2d4061;
    }
}

p {
    background-color: var(--main-color);
    color: var(--accent-color);
}

このようにすると、実際の色とプロパティ設定部分を切り離して書くことができます。そうすれば、ダークモード時にはこっちの変数を使うといった場合分けができます。

結構コストが掛かる

ダークモード時の色設定とか、結構コストがかかります。開発する時とかは、別途時間や予算が取れるのか発注側と相談して用意してもらうほうが良さそうです

実際にコーディングしてみましたが予想より工数が多いので、予算は別途必要になりそうですね。

この記事を書いた人

自身がプログラミングを独学で勉強し始めて躓いた経験を元に、これから勉強をする人に向けに「イラスト多めでわかりやすい記事」にこだわって情報を発信しています。

現在はフルスタックエンジニアとしてサービス開発などのお仕事をしています。