
【CSS_96】 ダークモードの切り替え設計
ダークモードの切り替え
はじめに:なぜダークモードが必要なのか?
現代のWebアプリケーションやサイトでは、「ダークモード」が標準の機能になりつつあります。
単なる流行ではなく、ユーザー体験(UX)・可読性・バッテリー効率といった観点での実用的なメリットが豊富にあります。
ダークモード設計の基本原理
2つのモード
ライトモード(Light Mode):背景が明るく、黒文字中心
ダークモード(Dark Mode):背景が暗く、白文字中心
切り替え方法の種類
OS設定連動(prefers-color-scheme)
ユーザーのOSの設定に従う
アプリ内トグル(手動切替)
ボタンやスイッチで明示的に切り替え
ローカル保存との併用
初回はOSに従い、その後は選択を記憶
実装ステップ全体像
CSS設計(変数設計)
メディアクエリによるOS連動
ユーザー手動切替の実装
状態保存(localStorage)
フレームワーク(React等)対応
アクセシビリティ対応
切替時のトランジション
1. CSS設計:カスタムプロパティ(CSS変数)
色の定義を変数化
:root {
--bg-color: #ffffff ;
--text-color: #000000 ;
}
[data-theme='dark'] {
--bg-color: #121212 ;
--text-color: #f1f1f1 ;
}実際のスタイルで使用
body {
background-color: var(--bg-color);
color: var(--text-color);
}2. OSのダークモード検知
◉ メディアクエリ prefers-color-scheme
これは自動でOSに従って切り替わるパターンです。
ただし、ユーザーの明示的な選択を上書きすることはしません。
3. ユーザー手動切り替え(JavaScript)
◉ HTML構造(例)
<button id="toggle-theme">テーマ切替</button>◉ JavaScriptで切替制御
const toggle = document.getElementById('toggle-theme');
toggle.addEventListener('click', () => {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
});4. 状態の永続化(localStorage)
◉ 初期読み込み時に設定を反映
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
document.documentElement.setAttribute('data-theme', savedTheme);
} else {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : 'light');
}5. フレームワーク対応:Reactでの実装例
◉ React Hookで管理
import { useEffect, useState } from 'react';
export const useDarkMode = () => {
const [theme, setTheme] = useState<'light' | 'dark'>(() => {
const saved = localStorage.getItem('theme');
if (saved) return saved as 'light' | 'dark';
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
});
useEffect(() => {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
}, [theme]);
const toggleTheme = () => {
setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'));
};
return { theme, toggleTheme };
};◉ 使用例
const App = () => {
const { theme, toggleTheme } = useDarkMode();
return (
<div>
<button onClick={toggleTheme}>
現在のテーマ: {theme}
</button>
</div>
);
};6. トランジションでUX向上
body {
transition: background-color 0.3s ease, color 0.3s ease;
}注意:トランジション適用前にDOMに即座にテーマ属性が付くようにすること。
7. アクセシビリティと視認性の注意点
コントラスト比
WCAG2.1で4.5:1以上推奨(文字と背景)
フォーカス状態
ダーク背景でも outline を明確に
スクロールバー
ブラウザ依存で見えにくくなる場合あり
色依存のUI
意味を色だけで伝えない工夫(アイコン等併用)
色の設計ヒント
背景
ライトモード: #ffffff
ダークモード: #121212
テキスト
ライトモード: #000000
ダークモード: #f1f1f1
アクティブボタン
ライトモード:#007BFF
ダークモード: #90CAF9
ボーダー
ライトモード:#e0e0e0
ダークモード: #333333
影
ライトモード:rgba(0,0,0,0.1)
ダークモード: rgba(0,0,0,0.5)
よくあるミスと対策
CSS変数を使っていない
管理が地獄に
→ 変数ベースの設計に徹する
切り替えが一瞬で反映されず白フラッシュ
初期テーマ設定が遅い
→ <script>で先にdata-theme設定
トグル切替が効かない
localStorageとUIが連動していない
→ Hook or Contextで状態一元化
高度な応用
Tailwind CSSでのダークモード対応(class戦略)
// tailwind.config.js
module.exports = {
darkMode: 'class', // または 'media'
}<body class="dark:bg-black dark:text-white bg-white text-black">切り替えは以下のように制御
document.documentElement.classList.toggle('dark');まとめ:良いダークモードとは?
可読性が高い(コントラスト重視)
パフォーマンス低下がない
CSS変数で柔軟に拡張可能
ユーザーに選択権を与える
アクセシブルで視覚的にも一貫