トークン反転だけでダークモードを実装する

ダークモードの設計方針

ダークモードを後から追加するのは、ほぼ 作り直しと同義 になりがち。最初からトークン設計に組み込んでおくと、トークンの値を反転するだけで全体が切り替わる。

私のサイトでは、.dark クラスがついたときに 10 個程度の CSS 変数を反転するだけで、<html.dark> に切り替わった瞬間に全コンポーネントがダークになる。

構造

これだけ。bg-paper text-ink のような Tailwind utility は CSS 変数を参照する ので、変数の値が変われば自動で全部置き換わる。

カテゴリ色も少し明るくする

ダーク背景に純色の青を載せると蛍光感が出る。明度を上げる方向でカテゴリ色を別途定義する:

ポイントは 彩度をそのままで明度だけ上げる。彩度を上げると目に痛い。

ダーク色のチェックは「画面の明るさを最低にした夜の自分の部屋」で行う。これがないと、明るいオフィスで OK でも家で読めない、という事態が起きる。

FOUC を防ぐ初期化スクリプト

<html.dark> をクラスとして付ける場合、HTML 初回ロード時に「light で表示 → script 実行で dark に切り替え」の 一瞬の白い chカ が出る。これを防ぐには _document.tsx で React のレンダ前に同期で class を付けるスクリプトを inject する。

これで body 描画前に .dark クラスが付くので、初期表示で白チラがない。

トグルは 3 値

light / dark / system の 3 値トグルにした。system は OS の prefers-color-scheme を尊重する。

シンプルな 2 値（light/dark）でも実用上は十分。3 値は個人的なこだわり。

まとめ…