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: 1wp_head の最初に出力することが重要です。CSSより後に実行されるとダークモードが一瞬後から適用されます
  • localStorage はユーザーのブラウザに保存されるため、別デバイスや別ブラウザでは引き継がれません
  • 画像や動画の色味もダークモードに合わせたい場合は filter: brightness(0.8)[data-theme="dark"] img に適用できます

まとめ

CSS変数で色を定義し、[data-theme="dark"] 属性でダークモードを切り替える実装が最もシンプルです。チラつき防止には wp_head の最初にインラインスクリプトで data-theme 属性を設定します。

お気軽にご相談ください

お見積りへ お問い合わせへ