はじめに
目的
本ドキュメントは、Webサイトをダークモードに対応させるための実践的な方法を分かりやすくまとめたガイドです。デザインや実装で押さえるべき基本から、具体的なコード例、運用時の注意点まで順を追って説明します。
対象読者
HTMLとCSSの基本知識があり、少しのJavaScriptを触ったことがある方を想定しています。初心者にも分かるように専門用語は最小限に留め、具体例で補います。
本書の構成
全9章で構成し、基本概念、CSSによる実装、CSS変数の活用、トグル実装、設定保存、メディアクエリ監視、ライブラリ活用、実装注意点まで網羅します。各章は単独でも参照しやすく作っています。
読み方のコツ
まず第2章〜第4章で基本を押さし、必要に応じてJavaScriptやライブラリの章を参照してください。実例を動かしながら学ぶと理解が深まります。
ダークモード対応の基本的な考え方
ダークモードとは
ダークモード対応とは、OSやブラウザの設定に合わせてサイトの配色を自動で切り替える仕組みです。ユーザーがOSでダークモードを有効にすると、背景を暗く、文字を明るく表示することで目の負担を軽減します。例えば、夜間に画面を見ても眩しくなりにくくなります。
仕組みのイメージ
ブラウザはユーザーの設定を伝えることができます。サイトはその情報を受け取り、対応する色や画像を使って表示を切り替えます。単純な例では、背景色と文字色を入れ替えるだけで十分効果があります。
ダークモードのメリット
- 視認性の向上:暗い環境で読みやすくなります。
- バッテリー節約:有機ELなどでは黒主体の表示が省エネになります。
- ユーザー満足度の向上:好みに合わせた表示が可能です。
デザイン上の注意点
- コントラストを確保してください。文字と背景は十分な差をつけます。
- 画像やアイコンは暗背景で見えなくなることがあります。代替画像や色替えを用意してください。
- ブランドカラーは単純に暗くするだけでなく、視認性を保つ形で調整します。
実装の考え方
まずは基本の配色を用意し、次に環境に応じて切り替える設計にします。CSS変数やメディアクエリを使うと管理しやすくなります。章ごとに具体的な実装例を紹介します。
CSSメディア特性を使った基本実装
概要
OSやブラウザがダークモードに設定されているかを自動で判定し、それに合わせてCSSを切り替える方法です。設定が切り替わると、ページを再読み込みせずに適用されます。
基本の書き方(例)
/* デフォルト(ライト想定) */
body { background: #fff; color: #111; }
/* ダークモード用 */
@media (prefers-color-scheme: dark) {
body { background: #121212; color: #e6e6e6; }
}
上のように@mediaで暗色系と明色系を分けて書きます。必要なら@media (prefers-color-scheme: light)も明示できます。
実務上のポイント
- 主要要素(背景、文字、リンク、ボタン)の色だけは必ず指定してください。視認性が大きく変わります。
- 画像やアイコンは色反転しないことが多いので、暗用の別画像を用意すると良いです。
- ブラウザやOSの設定に従うので、ユーザーの好みを尊重できます。
対応と注意点
- 主要なモダンブラウザでサポートされていますが、古い環境では無視されます。見た目が崩れる場合はライトのスタイルが適用されます。
- CSSの優先度やインラインスタイルで上書きされると期待通り動かないことがあります。スタイルの適用順に注意してください。
この方法は実装が簡単で効果が分かりやすく、まず試す価値が高いです。
CSS変数を使った効率的な実装
概念と利点
CSS変数(カスタムプロパティ)は色を名前で定義して使い回せます。複数箇所で同じ色を使っている場合、一度変えれば全体に反映されるため保守が楽になります。
基本の書き方
:rootでデフォルトを定義し、ダークテーマ用のスコープで上書きします。
:root{
--bg: #ffffff;
--text: #111827;
--primary: #0066cc;
}
[data-theme="dark"]{
--bg: #0b1220;
--text: #e6eef8;
--primary: #4ea3ff;
}
body{background:var(--bg,#fff);color:var(--text,#000);}
.btn{background:var(--primary);color:#fff}
prefers-color-schemeとの組み合わせ
ユーザーのOS設定を尊重する場合はメディアクエリで上書きします。
@media (prefers-color-scheme: dark){
:root{--bg:#0b1220;--text:#e6eef8;}
}
実用的なコツ
- 変数名はsemanticに(–bg, –text, –muted)にする。
- 部分的に色を変えたいときはコンポーネント単位で上書きする。
- 既定値をvar(…, fallback)で用意すると互換性が上がります。
この方法で色管理が一元化でき、テーマ切替や保守が楽になります。
JavaScriptを使ったトグルボタンの実装
概要
ユーザーが手動でダークモードを切り替える仕組みを作ります。ボタンのクリックでbodyにclassを付け外しし、スタイルを切り替えます。
HTML(例)
<button id="dark-mode-toggle" aria-pressed="false">ダークモード切り替え</button>
最低限のCSS(例)
:root{--bg:#ffffff;--text:#111}
body{background:var(--bg);color:var(--text)}
body.dark-mode{--bg:#121212;--text:#ffffff}
JavaScript(実装例)
const btn = document.getElementById('dark-mode-toggle');
btn.addEventListener('click', ()=>{
document.body.classList.toggle('dark-mode');
const isDark = document.body.classList.contains('dark-mode');
btn.setAttribute('aria-pressed', String(isDark));
btn.textContent = isDark ? 'ライトモードに戻す' : 'ダークモード切り替え';
});
注意点とアクセシビリティ
- ボタンにaria-pressedを設定し、状態を伝えます。\
- キーボード操作は
- 初期状態をOS設定に合わせたい場合はmatchMediaで判定できます(設定の保存は次章で扱います)。
この方法で、簡潔に手動切り替えを実装できます。
ユーザーの設定を保存する方法
概要
ユーザーが選んだライト/ダークモードを次回訪問時にも反映させるには、localStorageに保存します。ページ読み込み時にlocalStorageを確認して、body(またはhtml)にクラスを付けると簡単です。
実装例(シンプル)
<button id="theme-toggle" aria-pressed="false">切替</button>
<script>
const KEY = 'theme';
const toggle = document.getElementById('theme-toggle');
function applyTheme(theme){
document.body.classList.toggle('dark', theme === 'dark');
toggle.setAttribute('aria-pressed', theme === 'dark');
}
function loadTheme(){
const saved = localStorage.getItem(KEY);
if(saved) return applyTheme(saved);
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
applyTheme(prefersDark ? 'dark' : 'light');
}
toggle.addEventListener('click', ()=>{
const current = document.body.classList.contains('dark') ? 'dark' : 'light';
const next = current === 'dark' ? 'light' : 'dark';
applyTheme(next);
localStorage.setItem(KEY, next);
});
loadTheme();
</script>
ポイント
- localStorageは単純で扱いやすいです。値は文字列で保存されます。例: ‘dark’/’light’。
- アクセシビリティとして、トグルにaria-pressedやラベルを付けます。
- 初回はユーザーのOS設定(prefers-color-scheme)を参照すると自然です。
補足:複数タブ対応
別タブで設定が変わったときはstorageイベントで同期できます。
window.addEventListener('storage', (e)=>{
if(e.key === KEY) applyTheme(e.newValue);
});
この方法でユーザーの好みを安定して保存・復元できます。
JavaScriptでのメディアクエリ監視
概要
OS側のダークモード設定が変わったときに、ページを自動で切り替える方法を解説します。window.matchMediaを使い、prefers-color-schemeの変化をリアルタイムで監視します。
実装手順
- 初回読み込み時に現在の設定を適用する。
- matchMediaで監視オブジェクトを作る。
- changeイベントでボディのクラスを切り替える。
- ユーザーが手動でモードを選んで保存している場合は自動切替を行わないようにする。
サンプルコード
// 初期適用(保存設定がなければOS設定)
const saved = localStorage.getItem('theme');
const prefers = window.matchMedia('(prefers-color-scheme: dark)');
function applyTheme(isDark){
document.body.classList.toggle('dark-theme', isDark);
document.body.classList.toggle('light-theme', !isDark);
}
if(saved){
applyTheme(saved === 'dark');
} else {
applyTheme(prefers.matches);
}
// 監視の登録
function onPrefChange(e){
if(localStorage.getItem('theme')) return; // ユーザー優先
applyTheme(e.matches);
}
prefers.addEventListener('change', onPrefChange);
// ページ離脱時に解除するなら
// prefers.removeEventListener('change', onPrefChange);
注意点
- 古いブラウザではaddEventListenerでなくaddListenerが必要な場合があります。対応が必要です。
- ユーザー設定を尊重する設計にしてください。自動切替で予期せぬUI変化を起こさないようにします。
Darkmode.jsライブラリを使った簡単実装
概要
Darkmode.jsは、ページに簡単にダークモード切替ウィジェットを追加できる小さなライブラリです。OSの配色設定(prefers-color-scheme)にも対応し、スクリプトを読み込むだけで動作します。特定の要素を対象外にするには、darkmode-ignoreクラスを使います。
導入手順
- CDNまたはローカルでスクリプトを読み込みます。例:
<script src="https://unpkg.com/darkmode-js@1.5.7/lib/darkmode-js.min.js"></script>
- ページの任意の位置でインスタンスを作成します。
new Darkmode().showWidget();
これだけで右下にトグルが表示されます。
基本的な使い方とオプション
初期化時に表示位置や色を指定できます。例:
const options = { bottom: '64px', right: '32px', time: '0.5s' };
const darkmode = new Darkmode(options);
darkmode.showWidget();
要素の除外
ダークモードの影響を受けさせたくない要素にクラスを追加します。
<div class="darkmode-ignore">この部分はダークモードにしない</div>
ライブラリがその要素を除外します。
カスタマイズのポイント
- ボタン位置やアニメーションはオプションで調整します。
- 既存の色変数(CSS変数)と併用すると管理が楽になります。
- 必要ならウィジェットの表示・非表示を自前のトグルと連携できます。
注意点
- ライブラリは手早く導入できますが、全ページのデザイン整合は自分で確認してください。色や画像のコントラストを必ずチェックしてください。
ダークモード対応時の実装上の注意点
概要
body の背景色や基本色だけを切り替えるだけでは不十分です。個別に色を指定した要素や画像、外部コンポーネントまで確認し、全体の見え方を整える必要があります。
チェックリスト
- テキスト色:明示的にカラー指定した箇所を洗い出す
- 背景・カード・モーダル:複数の背景色を確認
- ボーダー・シャドウ:暗い背景でも視認性が保てるか
- 画像・アイコン:透明PNG/SVGやダーク用アセットを用意
- フォーム部品:プレースホルダーや選択時の見え方
- ホバー・フォーカス:状態ごとに色を設定
- サードパーティ:ウィジェットや埋め込みの色
よくある落とし穴
- inline style や高い CSS specificity により切替が効かない
- filter: invert() に頼ると色味が不自然になる
- 透過背景の重なりで読みづらくなる
アクセシビリティとテスト
- コントラスト比(本文は最低 4.5:1 を目安)を確認
- キーボード操作でフォーカスが見えるか確認
- OSのダーク設定、手動トグル、スナップショットで視覚確認
実装のヒント
- CSS変数を使い :root と .dark で差分を管理
- ルートクラス切替(document.documentElement.classList)を優先
- 例:
:root{--bg:#fff;--text:#222}
.dark{--bg:#0b0b0b;--text:#e6e6e6}
body{background:var(--bg);color:var(--text)}
丁寧に全要素を見直し、段階的に修正してください。












