ダークモード対応、最初は「切り替えボタンを1個付けて、CSSで背景と文字色を反転させれば5分で終わるでしょ」と完全に舐めてかかっていました。……結果、思った以上の大沼でした。夜な夜な画面の前で目をやられ、気づけば何日も泥沼に浸かる羽目になった落とし穴の数々を、自戒を込めて面白おかしく供養しておきます。
1. 透明PNGが忍者のように闇に消える
まず最初に直面したのが画像消滅事件です。白背景を前提に作った黒い線画アイコンやイラストを「背景透過のPNGにしてあるから安心!」とダークモードに放り込んだ瞬間、黒い背景に黒い線が溶けて完全なステルス状態になりました。
「あれ、画像読み込みエラー起きてる?」とDevToolsのNetworkタブを凝視したら、ステータスは律儀に200 OK。画像は消えたのではなく、闇と同化して忍者のように潜んでいただけでした。SVGならfill="currentColor"で文字色に連動させられますが、昔作った透過PNG画像たちは背景にうっすら白い座布団を敷くか、画像を丸ごと差し替える羽目になり、初手から早くも心が折れかけました。
2. 純白と漆黒の暴力(色の単純反転は眩しすぎる)
「ダークモード=背景が真っ黒(#000000)で、文字が真っ白(#ffffff)でしょ!」という短絡的な思考で組んだところ、暗い部屋で開いた瞬間に車のハイビームを直撃されたレベルのギラギラ感に襲われました。コントラスト比が高すぎて、文字が目に突き刺さって痛いのです。
調べてみると、ダークモードの基本は「真っ黒」ではなく「深いグレー(#121212や#181a1bなど)」を使い、文字色も少しトーンを落としたオフホワイトを使うのがセオリーとのこと。結局、全コンポーネントの配色バランスをゼロから見直すことになり、「え、これデザインを丸ごと2セット作ってるのと工数変わらなくない…?」と遠い目をすることになりました。
3. ページを開いた瞬間に食らう「閃光弾(ホワイトフラッシュ)」
個人的に一番手強かったのが、いわゆるFOUC(Flash of Unstyled Content)現象です。せっかくダークモードに設定して夜中に落ち着いて閲覧しているのに、リンクを踏んでページが切り替わる一瞬だけ、真っ白なライトモードの初期画面が「ピカーッ!」と炸裂するのです。
夜更けの暗い部屋でリロードを連打するたびに、自作サイトからスタングレネードを投げつけられているような気分になりました。原因は「HTMLが描画されたあと、JavaScriptでローカルストレージの設定を読み込んでダーク用クラスを付与していた」から。ページの<head>内の最上部で即時実行スクリプトを走らせ、描画前にクラスを確定させることでようやく閃光弾を封じることに成功しました。
4. 影(box-shadow)が闇に飲まれて虚無になる
ライトモードでおしゃれにカードを浮かび上がらせていたbox-shadow: 0 4px 16px rgba(0,0,0,0.08);。これがダークモードになった瞬間、「黒い背景の上に黒い影を落としても何も見えない」という物理の現実に直面します。
影が完全に虚無と化し、重なっていたカードと背景の境界線が消失して、全部がペタッと1枚の板に張り付いたように見えてしまいました。ダークモードでは「影で高さを出す」のではなく、「上に乗るカードほど背景色のグレーを少し明るくする(明度差で高さを表現する)」か、「ごく薄いボーダー線で輪郭を描く」必要があると知ったときは、UIデザイナーの偉大さに思わず手を合わせました。
5. フォーム部品とスクロールバーの置き去り事件
自分の書いたCSSは完璧にダーク対応できたと自画自賛していたら、input入力欄、チェックボックス、セレクトボックス、そして画面右端のスクロールバーだけが、ライトモードの真っ白な姿のまま鎮座していました。「お前たち、そこは空気読んでくれよ…」と頭を抱えましたが、実はCSSにcolor-scheme: light dark;を1行書くだけで解決します。
:root {
color-scheme: light dark;
}
これだけでブラウザ標準のフォーム部品やスクロールバーも、OSのテーマに合わせて一斉にダーク仕様に変身してくれます。最初からこれを知っていれば、inputの背景色を自前で上書きしてプレースホルダーの色と格闘する無駄な1時間を過ごさずに済んだのに…と深く反省しました。
| 直面した落とし穴 | やらかした原因 | 脱出のための対策 |
|---|---|---|
| 画像が見えなくなる(忍者化) | 白背景前提の黒線画・透過PNG | SVGでcurrentColorを使うか差し替え |
| 目が痛い(ハイビーム現象) | #000000と#ffffffの単純反転 | 深いグレーと柔らかい白で調整 |
| 閃光弾(ホワイトフラッシュ) | JSの設定読み込みタイミング遅延 | <head>最上部での即時クラス付与 |
| 影の虚無化(境界消失) | 黒背景に黒いbox-shadow | 背景の明度差や細い線で高さを表現 |
| フォーム部品だけ白いまま浮く | ブラウザ標準UIへの指示忘れ | color-scheme: light dark; を指定 |
「見た目の色を変えるだけ」という軽はずみな気持ちで足を踏み入れたダークモードの世界でしたが、光と影の物理法則からブラウザの描画タイミングまで、想像以上に深い学びと罠が詰まっていました。もしこれからダークモードを実装される方がいたら、ぜひ私の踏んだ地雷たちを踏み台にして、軽やかに飛び越えていってください…!😹
