2026年5月20日
2026年5月20日
WordPressにダークモード切り替えを実装する方法
はじめに
WordPressにダークモードを追加するには、CSS変数と prefers-color-scheme メディアクエリを組み合わせ、JavaScriptのトグルボタンで手動切り替えも可能にします。localStorage に設定を保存することで、次回訪問時も選択が維持されます。
症状・原因
- ダークモードに対応したサイトを作りたい
- ユーザーが手動でダークモードを切り替えられるようにしたい
- ページ読み込み時にダークモードが一瞬チラつく
- 設定を次回訪問時も維持したい
解決手順
ステップ1:CSS変数でライト・ダークカラーを定義する
/* style.css */
/* ライトモード(デフォルト) */
:root {
--bg-color: #ffffff;
--text-color: #1d2327;
--text-muted: #50575e;
--border-color: #c3c4c7;
--card-bg: #f6f7f7;
--link-color: #2271b1;
--header-bg: #1d2327;
}
/* システムがダークモードの場合に自動適用 */
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg-color: #1a1a2e;
--text-color: #e2e8f0;
--text-muted: #94a3b8;
--border-color: #334155;
--card-bg: #16213e;
--link-color: #60a5fa;
--header-bg: #0f0f23;
}
}
/* 手動でダークモードを選択した場合 */
[data-theme="dark"] {
--bg-color: #1a1a2e;
--text-color: #e2e8f0;
--text-muted: #94a3b8;
--border-color: #334155;
--card-bg: #16213e;
--link-color: #60a5fa;
--header-bg: #0f0f23;
}
/* 変数を適用 */
body {
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s, color 0.3s;
}
a { color: var(--link-color); }
.site-header { background-color: var(--header-bg); }
.card { background: var(--card-bg); border: 1px solid var(--border-color); }
ステップ2:チラつき防止スクリプトを に追加する
// functions.php — チラつき防止(インラインスクリプトを最初に出力)
add_action('wp_head', function(): void {
?>
<script>
(function() {
var saved = localStorage.getItem('darkMode');
var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (saved === 'dark' || (!saved && prefersDark)) {
document.documentElement.setAttribute('data-theme', 'dark');
} else if (saved === 'light') {
document.documentElement.setAttribute('data-theme', 'light');
}
})();
</script>
<?php
}, 1); // 優先度1で他のすべてより先に出力
ステップ3:トグルボタンのHTMLとJavaScriptを実装する
// functions.php — ヘッダーナビにトグルボタンを追加
add_action('wp_footer', function(): void {
?>
<button id="dark-mode-toggle" aria-label="ダークモード切り替え" aria-pressed="false">
<span class="icon-sun">☀️</span>
<span class="icon-moon">🌙</span>
</button>
<?php
});
// js/dark-mode.js
(function() {
var btn = document.getElementById('dark-mode-toggle');
if (!btn) return;
function getCurrentTheme() {
return document.documentElement.getAttribute('data-theme') ||
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
}
function setTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('darkMode', theme);
btn.setAttribute('aria-pressed', String(theme === 'dark'));
}
// 初期状態を設定
btn.setAttribute('aria-pressed', String(getCurrentTheme() === 'dark'));
btn.addEventListener('click', function() {
setTheme(getCurrentTheme() === 'dark' ? 'light' : 'dark');
});
// システム設定変更を検知
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
if (!localStorage.getItem('darkMode')) {
setTheme(e.matches ? 'dark' : 'light');
}
});
})();
/* トグルボタンのスタイル */
#dark-mode-toggle {
position: fixed;
bottom: 24px;
right: 24px;
width: 48px;
height: 48px;
border-radius: 50%;
border: 2px solid var(--border-color);
background: var(--card-bg);
cursor: pointer;
font-size: 1.2rem;
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
transition: transform 0.2s;
}
#dark-mode-toggle:hover { transform: scale(1.1); }
[data-theme="dark"] .icon-sun { display: block; }
[data-theme="dark"] .icon-moon { display: none; }
:root:not([data-theme="dark"]) .icon-sun { display: none; }
:root:not([data-theme="dark"]) .icon-moon { display: block; }
ステップ4:スクリプトを正しくエンキューする
// functions.php
add_action('wp_enqueue_scripts', function(): void {
wp_enqueue_script(
'dark-mode',
get_stylesheet_directory_uri() . '/js/dark-mode.js',
[],
filemtime(get_stylesheet_directory() . '/js/dark-mode.js'),
true
);
});
注意事項
- チラつき防止スクリプトは
priority: 1でwp_headの最初に出力することが重要です。CSSより後に実行されるとダークモードが一瞬後から適用されます localStorageはユーザーのブラウザに保存されるため、別デバイスや別ブラウザでは引き継がれません- 画像や動画の色味もダークモードに合わせたい場合は
filter: brightness(0.8)を[data-theme="dark"] imgに適用できます
まとめ
CSS変数で色を定義し、[data-theme="dark"] 属性でダークモードを切り替える実装が最もシンプルです。チラつき防止には wp_head の最初にインラインスクリプトで data-theme 属性を設定します。