[Astro] prefers-color-scheme で自動ダークモード対応にする

Tech
[Astro] prefers-color-scheme で自動ダークモード対応にする

このブログは、OS のテーマ設定に合わせて自動でダークモードに切り替わるようにしています。トグルボタンは置かず、prefers-color-scheme に任せるシンプルな方式です。実装をまとめます。

方針:トグルなし、OS追従

ダークモードには「ボタンで手動切替」と「OS設定に追従」の2方式がありますが、個人ブログなら OS追従が一番ラクです。状態管理もlocalStorageも要りません。CSS だけで完結します。

ベースの配色を CSS で切り替える

body などの基本色は、@media (prefers-color-scheme: dark) で上書きします。

/* src/styles/global.css */
body {
  color: var(--color-text);
  background-color: var(--color-bg);
}

@media (prefers-color-scheme: dark) {
  body {
    color: #e0e0e0;
    background-color: #1a1a2e;
  }
}

コンポーネントは Tailwind の dark: で

個別要素は Tailwind の dark: バリアントで指定します。Tailwind CSS v4 の dark: は、デフォルトで prefers-color-scheme: dark に対応しているので、設定不要でそのまま使えます(クラス方式にしたい場合だけ @custom-variant の設定が要る)。

<body class="bg-[var(--color-bg)] text-[var(--color-text)] dark:bg-[#1a1a2e] dark:text-[#e0e0e0]">

カードなども同様に。

<div class="bg-white dark:bg-[#16213e] ...">

CSS変数(--color-*)でライト配色を定義しておき、ダークは dark: で個別に当てる、という併用にしています。

記事本文(prose)も忘れずに

Typography プラグインの prose は、ダーク用に dark:prose-invert を足すだけで本文の文字色などが反転します。

<div class="prose prose-lg dark:prose-invert max-w-none">
  <slot />
</div>

コードハイライト(Shiki)のダーク対応は別途必要ですが、それは別記事にまとめています。

メモ

  • OS追従は実装が最小で、状態のズレも起きない。個人ブログには十分。
  • Tailwind v4 の dark: はデフォルトで prefers-color-scheme ベース。クラストグルにしたいときだけ @custom-variant dark (&:where(.dark, .dark *)); のような設定を足す。
  • 確認は OS のダークモードを切り替えるか、ブラウザの DevTools で prefers-color-scheme をエミュレートするのが早い。

ボタンを置かない割り切りで、コードはかなりスッキリしました。

Astro, Tailwind CSS, CSS