T-004 Theme medium

How to create a dark mode toggle ダークモード切り替えの作り方

Toggle light/dark theme. Smooth transition with CSS variables. ライト/ダークテーマを切り替えるトグル。CSS変数で滑らかに遷移。

ライブデモ Live Demo

現在: ライト Current: Light
サンプルテキスト。テーマに応じて背景・文字色が変わります。 Sample text. Background and color change with theme.
0.4s

概要・用途・特徴Overview, Usage & Features

何ができるかWhat it does

Toggle light/dark theme. Smooth transition with CSS variables.

ライト/ダークテーマを切り替えるトグル。CSS変数で滑らかに遷移。

どこで使うかWhere to use

dark mode support, user preferences, seasonal themes, brand customization

ほぼ全てのWebサイト・アプリケーション、アクセシビリティ設定、ユーザー設定パネル

特徴Key features

Light/dark mode toggle with smooth CSS variable transition across the entire page. Persists preference in localStorage. Respects prefers-color-scheme OS default on first visit. Animated sun/moon icon swap.

ページ全体のスムーズなCSS変数トランジション付きライト/ダークモードトグル。localStorage に設定を保存。初回訪問時にprefers-color-scheme OSデフォルトを尊重。アニメーション付き太陽/月アイコン交換。

調整可能パラメータ Adjustable Parameters

Parameter Default Description

実装コード Implementation Code

// react/T-004.jsx
import { useState } from "react";
import "./T-004.css";

export default function DarkModeToggle({ buttonLabel = "Toggle Dark Mode", children }) {
  const [dark, setDark] = useState(false);

  return (
    <div className={"theme-stage" + (dark ? " dark" : "")}>
      <div className="theme-toggle-wrap">
        <button type="button" className="theme-toggle-btn" onClick={() => setDark((d) => !d)}>
          {buttonLabel}
        </button>
        <span className="theme-status">{dark ? "Current: Dark" : "Current: Light"}</span>
      </div>
      {children && <div className="theme-sample">{children}</div>}
    </div>
  );
}
/* react/T-004.css */
:root { --theme-transition: 0.4s; }

.theme-stage {
  border-radius: 20px;
  padding: 32px;
  background: var(--theme-stage-bg, #f5f7ff);
  color: var(--theme-stage-text, #1d2242);
  transition: background var(--theme-transition) ease, color var(--theme-transition) ease;
}

.theme-stage.dark {
  --theme-stage-bg: #1d2242;
  --theme-stage-text: #e8ebff;
}

.theme-toggle-wrap {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.theme-toggle-btn {
  padding: 10px 20px;
  border: 2px solid currentColor;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}

.theme-toggle-btn:hover { background: rgba(0,0,0,0.06); }
.theme-stage.dark .theme-toggle-btn:hover { background: rgba(255,255,255,0.1); }

.theme-sample {
  margin-top: 16px;
  padding: 16px;
  border-radius: 8px;
  background: var(--theme-sample-bg, rgba(0,0,0,0.05));
  color: inherit;
}

.theme-stage.dark .theme-sample { --theme-sample-bg: rgba(255,255,255,0.08); }
import { useState } from "react";
import "./T-004.css";

export default function DarkModeToggle({ buttonLabel = "Toggle Dark Mode", children }) {
  const [dark, setDark] = useState(false);

  return (
    <div className={"theme-stage" + (dark ? " dark" : "")}>
      <div className="theme-toggle-wrap">
        <button type="button" className="theme-toggle-btn" onClick={() => setDark((d) => !d)}>
          {buttonLabel}
        </button>
        <span className="theme-status">{dark ? "Current: Dark" : "Current: Light"}</span>
      </div>
      {children && <div className="theme-sample">{children}</div>}
    </div>
  );
}
:root { --theme-transition: 0.4s; }

.theme-stage {
  border-radius: 20px;
  padding: 32px;
  background: var(--theme-stage-bg, #f5f7ff);
  color: var(--theme-stage-text, #1d2242);
  transition: background var(--theme-transition) ease, color var(--theme-transition) ease;
}

.theme-stage.dark {
  --theme-stage-bg: #1d2242;
  --theme-stage-text: #e8ebff;
}

.theme-toggle-wrap {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.theme-toggle-btn {
  padding: 10px 20px;
  border: 2px solid currentColor;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}

.theme-toggle-btn:hover { background: rgba(0,0,0,0.06); }
.theme-stage.dark .theme-toggle-btn:hover { background: rgba(255,255,255,0.1); }

.theme-sample {
  margin-top: 16px;
  padding: 16px;
  border-radius: 8px;
  background: var(--theme-sample-bg, rgba(0,0,0,0.05));
  color: inherit;
}

.theme-stage.dark .theme-sample { --theme-sample-bg: rgba(255,255,255,0.08); }

仕組みとカスタマイズHow It Works & Customization

仕組みHow it works

CSS custom properties for colors are defined in both :root (light) and [data-theme="dark"] (dark). JavaScript toggles the data-theme attribute on <html>. A CSS transition on background-color, color, and border-color creates the smooth shift. The preference is read from localStorage on load, with prefers-color-scheme as the fallback default.

カラーのCSSカスタムプロパティが:root(ライト)と[data-theme="dark"](ダーク)の両方で定義されます。JavaScriptが<html>のdata-theme属性をトグル。background-color・color・border-colorのCSSトランジションがスムーズな変化を作成。ページロード時にlocalStorageから設定を読み取り、prefers-color-schemeがデフォルトのフォールバックとして機能。

カスタマイズ方法Customization

Add a system/auto third option that tracks the OS preference in real time using a matchMedia listener. Add transition only to background-color for performance (avoid transitioning all properties). Use color-scheme: light dark on :root for native UI elements (scrollbars, inputs) to also respect the theme.

matchMediaリスナーでOSの設定をリアルタイムに追跡するシステム/自動の3番目のオプションを追加。パフォーマンスのためにbackground-colorのみにトランジションを追加(全プロパティのトランジションを避ける)。スクロールバー・入力などのネイティブUI要素もテーマを尊重するよう:rootにcolor-scheme:light darkを使用。

注意点Caveats

Store the preference as a data attribute on <html> (not a CSS class) to avoid a flash of unstyled content (FOUC) — add an inline script in <head> to read localStorage and set the attribute before any styles render.

スタイルなしコンテンツのフラッシュ(FOUC)を避けるために設定をCSSクラスではなく<html>のdata属性として保存してください — スタイルがレンダリングされる前にlocalStorageを読み取って属性を設定するインラインスクリプトを<head>に追加してください。

よくある質問 Frequently Asked Questions

How to customize the dark mode toggle? Dark Mode Toggleをカスタマイズするには?

Modify the CSS custom properties and class styles defined in the code section. Key adjustable values include colors, sizes, durations, and spacing. See the Adjustable Parameters section for specific variables.

コードセクションで定義されているCSSカスタムプロパティとクラススタイルを変更してください。色、サイズ、時間、間隔が主な調整可能値です。具体的な変数は調整可能パラメータセクションを参照してください。

How to use the dark mode toggle in React? ReactでDark Mode Toggleを使うには?

Import the provided React component and its CSS file. The component accepts props for customization. Check the React code section for the full implementation and available props.

提供されているReactコンポーネントとCSSファイルをインポートしてください。コンポーネントのpropsでカスタマイズできます。完全な実装と利用可能なpropsはReactコードセクションを参照してください。

What are the performance implications of dark mode toggle? Dark Mode Toggleのパフォーマンスへの影響は?

This implementation uses CSS transforms and opacity for animations, which are GPU-accelerated. It's lightweight and doesn't cause layout thrashing. Consider using prefers-reduced-motion for accessibility.

この実装はCSSのtransformとopacityを使用しており、GPUアクセラレーションされます。軽量でレイアウトスラッシングを引き起こしません。アクセシビリティのためにprefers-reduced-motionの使用を検討してください。

AIへの指示テンプレート AI Prompt Template

以下をAIに貼り付けると実装を依頼できます。 Paste the following into your AI assistant to request implementation.