この記事の目次
CSSダークモード対応のやり方とは
ダークモード対応とは、利用者のOSやブラウザが「暗い配色」を選んでいるとき、サイトも暗い配色で表示することです。CSSでは、メディア特性 prefers-color-scheme で設定を読み取り、色を切り替えます。MDNでは、2020年1月から主要ブラウザで広く使えるとされています。
基本(構文・仕組み)
| 仕組み | 役割 |
|---|---|
@media (prefers-color-scheme: dark) |
暗い配色を好む利用者のときだけCSSを適用 |
color-scheme: light dark |
サイトが両方に対応すると宣言。入力欄やスクロールバーなどの標準部品の配色も合わせる |
light-dark(明, 暗) |
明暗の2色を1行で書く関数 |
| CSSカスタムプロパティ | 色を変数にして、切り替えを1か所にまとめる |
基本の型は、色を変数にして、ダーク時に変数だけを差し替えることです。
:root {
color-scheme: light dark;
--bg: #ffffff; --text: #1f2937; --link: #1d4ed8; --surface: #f3f4f6;
}
@media (prefers-color-scheme: dark) {
:root { --bg: #121212; --text: #e5e7eb; --link: #93c5fd; --surface: #1e1e1e; }
}
body { background: var(--bg); color: var(--text); }
a { color: var(--link); }
サンプルコード(実行結果つき)
OS設定に従いつつ、利用者がボタンで手動切り替えもできる例です。data-theme 属性を使います。
:root[data-theme="light"] { --bg:#ffffff; --text:#1f2937; --link:#1d4ed8; --surface:#f3f4f6; color-scheme: light; }
:root[data-theme="dark"] { --bg:#121212; --text:#e5e7eb; --link:#93c5fd; --surface:#1e1e1e; color-scheme: dark; }
.ld { background: light-dark(#fff7ed, #3b2a1a); color: light-dark(#7c2d12, #fed7aa); }
// 手動切り替え(localStorage の保存は省略)
document.documentElement.dataset.theme = 'dark';
<head> に <meta name="color-scheme" content="light dark"> を入れると、CSS読み込み前の一瞬の白い画面を減らせます。
動作確認(検証環境と結果)
- 環境: Windows 11、Microsoft Edge 154(Chromium系、headless)。ログは
C:Tempks2techtestscss-dark-mode.md。 - 実行:
render.ps1で幅1200・390指定で描画し、data-themeを付け替えてgetComputedStyleを確認しました。 - 結果: この環境の headless Edge では
matchMedia('(prefers-color-scheme: dark)')が true で、何も指定しない状態の背景はrgb(18, 18, 18)でした。data-theme=darkで背景rgb(18, 18, 18)・文字rgb(229, 231, 235)、data-theme=lightで背景rgb(255, 255, 255)に切り替わりました。light-dark()は、暗いときrgb(59, 42, 26)、明るいときrgb(255, 247, 237)でした。 - 注意: 環境が最初からダーク設定だったため、OSがライトの場合の自動表示は未検証です。
localStorageによる保存、Safari・Firefox の表示も未検証です。
CSSダークモード対応のやり方の注意点
- 暗い背景に純白の文字を置くと、まぶしく感じる人もいます。灰色寄りの色(上の例では
#e5e7eb)を使う案もあります。 - ダーク用の色も、WCAG 1.4.3 のコントラスト比(通常の文字で4.5:1以上、大きな文字で3:1以上)を満たす必要があります。例えば
#e5e7ebと#121212の組み合わせは約15.1:1でした(計算ツールで算出)。→ コントラスト比 - 明るい背景で選んだ青(
#2563eb)は、#121212の上では約3.6:1と不足します。ダークでは明るい青(#93c5fd、約10.4:1)に変えます。 - 画像やロゴは、背景が透明でないと暗い背景で浮くことがあります。
light-dark()は比較的新しい関数です。対象ブラウザを確認し、必要なら変数方式を使います。
CSSダークモード対応のやり方でよくあるミス
- 背景だけ変えて、リンクや枠線の色を忘れる。
- 単純に色を反転させ、コントラストが不足する。
- 影(
box-shadow)が暗い背景で見えなくなることに気づかない。 color-schemeを宣言せず、入力欄やスクロールバーだけ白いままになる。- 手動切り替えの選択を保存せず、再読み込みで戻る。
ブラウザ対応・バージョン
prefers-color-scheme は、MDNでは2020年1月から主要ブラウザで広く使えます。color-scheme や light-dark() は後から追加された機能です。互換性はMDNと can I use で確認してください。
CSSダークモード対応のやり方のチェックリスト
- 色を変数にして、切り替えを1か所にまとめたか。
color-scheme: light darkを宣言したか。- ダークの文字色・リンク色も、コントラスト比4.5:1以上か。
- 画像・アイコン・影の見え方を確認したか。
- 手動切り替えを付ける場合、選択を保存するか。
CSSダークモード対応のやり方のFAQ(よくある質問)
Q. ダークモードは必須ですか?
A. 必須ではありません。ただ、OS設定を尊重すると、夜間の閲覧が快適になる利用者もいます。優先度は、サイトの性格で判断します。
Q. 手動切り替えはどう作りますか?
A. ルート要素に data-theme を付け、変数を差し替える方式が簡単です。保存には localStorage を使いますが、無効な環境でも動くようにします。
Q. 画像を暗い背景に合わせるには?
A. picture と media="(prefers-color-scheme: dark)" で画像を切り替えるか、filter: brightness() で調整します。
筆者の見解(CSSダークモード対応のやり方)
私見では、ダークモードは「色を変数で管理しているか」の確認になる機能だと考えます。最初から色をトークン化しておけば、対応の手間はほとんど変数の差し替えで済みます。反対に、色を直書きしているサイトでは、手間が大きくなります。まずは文字・背景・リンクの3色から始めるのが現実的です。

