ウェブサイトにダークモードを追加する方法(CSS、Tailwind、Next.js)
ホーム
ウェブサイトにダークモードを追加する方法
ダークモードの追加方法:CSS、Tailwind、Next.js | We.Inc
OSの配色設定に従うメディアクエリ、CSS変数、light-dark()、ライト/ダーク/システムの切り替え、Tailwind v4、next-themesで、読み込み時のちらつきなしにダークモードを追加します。
最も簡単なダークモードはCSSだけで実現できます。color-scheme: light dark を宣言し、色をカスタムプロパティにまとめ、@media (prefers-color-scheme: dark) の中で入れ替えます。手動で切り替えたい場合は、html要素にクラスかデータ属性を設定し、選択をlocalStorageに保存して、<head>内の小さなインラインスクリプトで適用します。こうすれば、間違ったテーマが一瞬表示されることはありません。
どの方法が自分の技術スタックに合うか
技術スタック OSの設定に従う 手動の切り替え 要となる部分
素のCSS はい いいえ @media (prefers-color-scheme: dark)
CSS + 小さなスクリプト はい はい html の data-theme + head 内のインラインスクリプト
Tailwind CSS v4 はい、デフォルトで @custom-variant を使えば可能 dark: ユーティリティ
Next.js App Router はい はい next-themes の ThemeProvider
ダークモードには3つの要素があります。切り替え可能な色、どちらの色の組を使うかを決める仕組み、そして最初の描画で正しく表示されるためのタイミングです。下のプレビューでは、サンプルのレイアウトでライト、ダーク、システムを切り替えられます。続く各セクションでは、素のCSS、Tailwind、Next.js向けの正確なコードを紹介します。
プレビューでライト、ダーク、システムのいずれかを選びます。システムはOSの設定に従い、設定を変えるとその場で更新されます。 フォームの入力欄やスクロールバーも切り替わることに注目してください。これはcolor-schemeプロパティの働きです。 下の例から自分の技術スタックを選んでコードをコピーします。ちらつき防止のスクリプトは<head>内にインラインで置きます。 各モードで再読み込みしてテストし、さらにOSをダークに設定して何も保存していない状態でも1回確認します。
真っ白の上の真っ黒をそのまま反転させるのはやめましょう。少し明るめのダークグレーにオフホワイトの文字を合わせるほうが、長時間でも読みやすくなります。 両方のテーマでコントラストを確認し直しましょう。白の上では基準を満たすブランドの青が、ダークグレーの背景では満たさないことがあります。 画像やロゴにはダーク用のバリエーションか透明な背景を用意し、暗いページの上で白い箱が浮いて光らないようにしましょう。 「システム」は単語として保存するのではなく、保存値がない状態として扱いましょう。そうすれば、後でOSの設定が変わっても追従できます。 <meta name="color-scheme" content="light dark"> を追加すると、CSSが届く前にブラウザーが暗いキャンバスを描画します。
よくある質問
ダークモードでページを読み込むときの白いちらつきを防ぐには?
最初の描画の前にテーマを決めます。保存された選択とシステムの設定を読み取り、html要素にクラスか属性を設定する小さなブロッキングスクリプトを、<head>の先頭に置きます。<body>末尾のスクリプトやフレームワークのコンポーネント内のスクリプトでは、実行が遅すぎます。
Tailwindのダークモードはどう動きますか?
Tailwind v4では、dark: バリアントはデフォルトでOSの配色設定のメディアクエリを使うため、dark:bg-gray-900 はシステムがダークのときに適用されます。切り替えボタンで制御するには、CSSに @custom-variant dark (&:where(.dark, .dark *)); を追加し、html要素にdarkクラスを付けます。
Next.jsでダークモードを追加するには?
一般的なのは、MITライセンスのnext-themesパッケージを使う方法です。ルートレイアウト内でアプリをそのThemeProviderで包み、htmlタグにsuppressHydrationWarningを追加し、クライアントコンポーネントでuseThemeから得たsetThemeを呼び出します。ちらつき防止のスクリプトは自動で挿入されます。
color-schemeは何をするものですか?
ページが対応する配色をブラウザーに伝えます。これにより、フォームのコントロール、スクロールバー、ページの背景といった組み込みの部分が、合った色で表示されます。また、light-dark()関数が2番目の値を選ぶには、ルートに color-scheme: light dark を設定する必要があります。
ダークモードはシステムに従うべきですか、切り替えボタンを付けるべきですか?
両方です。利用者はすでにシステムの設定を選んでいるので、それをデフォルトにしましょう。そのうえでライト、ダーク、システムの切り替えを用意し、訪問者が自分のサイトでだけ設定を上書きできるようにします。
まず変数で配色を作る
色には見た目ではなく役割で名前を付けます。--bg、--surface、--text、--muted、--accent、--border のようにです。コンポーネントはこれらの名前だけを使います。そうすれば、テーマの切り替えは1か所で少数の変数を定義し直すだけで済みます。 light-dark()関数を使うと、1つの宣言に両方の値を持たせられるので、さらに短く書けます。MDNではBaseline 2024とされているため、利用者層に必要なら古いブラウザー向けの代替を残しておきましょう。
切り替えをアクセシブルにする
切り替えは、わかりやすい名前を持つ本物のボタンにします。2状態のスイッチならaria-pressedを使い、3つの選択肢なら、順番に切り替わるアイコンより小さなラジオボタンのグループかセレクトボックスのほうがわかりやすくなります。 余計な読み上げは不要です。目に見える変化がフィードバックであり、コントロール自体の状態がスクリーンリーダーの利用者に何が選ばれているかを伝えます。
サーバーレンダリングとハイドレーション
サーバーは最初のリクエストで訪問者のテーマを知ることができないため、描画されたHTMLに「ライトに切り替え」のようなテーマ固有の文言を含められません。切り替えのラベルはコンポーネントのマウント後に描画するか、中立的な内容を描画しましょう。 next-themesがhtmlタグにハイドレーション警告を抑える属性を求めるのも同じ理由です。Reactがハイドレーションする前に、そのスクリプトがhtmlの属性を変更するからです。
1. システムに従う純粋なCSS
prefers-color-schemeで入れ替える変数
結果のフレームは端末の設定に従います。システムをダークに変えると、再読み込みなしで更新されます。
light-dark()で同じことをする
1色につき1つの宣言で済みます。ルートにcolor-schemeが必要で、MDNではBaseline 2024とされています。
2. ちらつきのないライト、ダーク、システムの切り替え
<head>の先頭に置くインラインスクリプト
<body>が描画される前に実行されます。何も保存されていなければ何もしないので、メディアクエリが引き続きシステムに従います。
属性とシステムの両方を尊重するCSS
属性があればそちらが優先されます。なければメディアクエリが決めます。
切り替えそのもの
3つの選択肢を持つセレクトボックスです。システムを選ぶと保存値が削除されます。
3. Tailwind CSS v4
クラスで切り替えるdark: ユーティリティ
@custom-variantの行がなければ、dark: はOSの配色設定に従います。行があれば、html上のdarkクラスがテーマを制御します。
4. next-themesを使うNext.js App Router
ルートレイアウトとクライアント側のプロバイダー
ThemeProviderはクライアントコンポーネントなので、専用のファイルに置きます。attribute="class" でTailwindのdarkクラスと組み合わせます。
マウントまで待つ切り替え
サーバーはテーマを知らないため、ハイドレーションの不一致を避けるよう、コントロールはマウント後に描画します。
テーマのプレビュー
ライト、ダーク、システムを切り替えて、フォームのコントロールを含むサンプルのレイアウトが変わる様子を確認できます。
テーマ
ライト
ダーク
システム(現在ダーク)
システム(現在ライト)
Harbour Bakery
サンプル
メニュー
店舗案内
朝7時に焼きたて
サワードウ、ライ麦パン、シード入りのパンを毎朝。
メールで注文
[email protected]
今週のおすすめ
使用中の配色:ダーク、color-scheme: dark
使用中の配色:ライト、color-scheme: light
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る