結論
プロのダークモードは「反転」ではなく「再設計」だ。土台に純黒#000000を使わずダークグレー**#121212**を基準サーフェスに置き、奥行きは影ではなく「上の面ほど明るくする」半透明白オーバーレイのランプ(0dp=0%→24dp=16%)で表現する。そのうえでアクセント色は彩度を落とした明トーンへ、本文は純白ベタをやめて白の不透明度87/60/38%で階層化する——この3点が揃って初めてダークモードは「映える」。
01 — 背景は純黒ではなく #121212
「ダークだから真っ黒」が最初の落とし穴。純黒#000000に純白#FFFFFFを乗せるとコントラストが過剰になり、文字がにじむハレーション/ブルーミング(縁が発光して振動する現象)を起こす。乱視・ディスレクシアのユーザーで可読性が落ち、OLEDではスメアも出る。基準を**#121212**にすると、影や標高オーバーレイが表現できるうえ、純白本文でも約15.8:1という十分なコントラストに収まる。
primaryDark theme — Material Design (M2)
blogDark Mode Color Design — ColorArchive
02 — 奥行きは影ではなく「面の明るさ」で出す
ライトモードは影だけで重なりが伝わるが、ダークモードでは影は「光の反転=暗い値」なので暗背景上ではほとんど見えず、平坦で安っぽくなる。階層を伝える唯一の手はトーナル・エレベーション——#121212の上に白オーバーレイを重ね、標高が高いほど明るくする。正準ランプは 1dp=5%、3dp=8%、8dp=12%、24dp=16%。結果、card(1dp)≈#1E1E1E、dialog(3dp)≈#2C2C2C になる。
primaryDark theme — Material Design (M2)
bloggood dark mode shadows & elevation — parker.mov
03 — 上の面は必ず下の面より明るく
積層UI(ドロワー/シート/ポップオーバー)で前後関係を伝えるルールはシンプルだ。「上のサーフェスが下より明るいときだけ、重なり順が読める」。各レイヤーで背景に+4〜8%の明度(=上記オーバーレイ)を足す。下のbadは全レイヤー同色で影だけ足したもの——どれが手前か判然としない。goodは #1E1E1E→#272727→#323232 と上に行くほど明るく、奥行きが一目で伝わる。
blogDesigning a Scalable and Accessible Dark Theme — fourzerothree
primaryElevation — Atlassian Design
04 — アクセント色は彩度を落とした明トーンへ
ライトモードの飽和したブランド色をそのまま乗せると、暗背景で視覚的振動(vibration)を起こして眼精疲労を招き、WCAG AA 4.5:1も割って読みにくい。Materialはトーン200付近(範囲200〜50)の明るく彩度を落とした色を推奨する。目安は全体-10〜20%、青/シアンは-20〜30%、鮮やかな赤は70〜80%まで落とす。#6200EE→#B39DDB のように明トーンへ振り直す。
blogDesign for the Dark Theme — Snapp Mobile
primaryDark theme — Material Design (M2)
05 — テキストは白の不透明度で階層化(87/60/38%)
本文に純白#FFFFFFをベタ塗りするとギラついて、しかも強調レベルの階層が作れない。プロは白を**不透明度87/60/38%**で運用する——高強調87%(見出し・本文)、中強調60%(補助・キャプション)、無効38%。ベタが要る場面は#E0E0E0〜#F0F0F0のオフホワイトに。これで過剰コントラストを避けつつ、見出し→本文→キャプションの濃淡が自然に立ち上がる。
secondaryDark Theme with MDC — Chris Banes
06 — 影を使うなら色付き多層か、1pxヘアラインで
オーバーレイだけで境界が曖昧なとき、または最上位レイヤーに追加の奥行きが欲しいとき——ライトモードの黒い影を流用してはいけない。暗背景で黒影は見えないか、見えても汚い。手は2つ。(1) 小さいUIやテーブルは1pxの淡いヘアライン(rgba(255,255,255,.08))で面を区切る。(2) 影を使うなら純黒透明ではなく彩度のある色味を付け(例 hsl(220deg 60% 50%))、低不透明度で多層に重ねる。Atlassianは最上位の標高にのみ影を残す。
primaryElevation — Atlassian Design
blogDesigning Beautiful Shadows in CSS — Josh W. Comeau
実装スニペット
標高サーフェスのトークン(白オーバーレイ正準ランプ)。影ではなくこの明度差で奥行きを出す。
:root[data-theme="dark"] {
--surface-0: #121212; /* 0dp base */
--surface-1: #1E1E1E; /* 1dp = 5% white overlay */
--surface-2: #232323; /* 2dp = 7% */
--surface-3: #252525; /* 3dp = 8% -> cards/dialogs */
--surface-4: #272727; /* 4dp = 9% */
--surface-6: #2C2C2C; /* 6dp = 11% */
--surface-8: #2E2E2E; /* 8dp = 12% -> app bars */
--surface-12: #323232; /* 12dp = 14% */
--surface-16: #353535; /* 16dp = 15% */
--surface-24: #373737; /* 24dp = 16% (max) */
}
オーバーレイをCSSで合成(任意のブランド面)。標高が上がるほど不透明度を上げる(最大16%)。
.card {
/* base #121212 + 8% white overlay (≈3dp相当) */
background-image:
linear-gradient(rgba(255,255,255,.08), rgba(255,255,255,.08));
background-color: #121212;
border-radius: 12px;
}
.card--branded {
/* #121212 + 8% primary でブランド面に (例: #1F1B24) */
background-image:
linear-gradient(rgba(124,77,255,.08), rgba(124,77,255,.08));
background-color: #121212;
}
テキスト強調レベル(白の不透明度 87/60/38%)。#121212上で高強調はおよそ15:1級、AA 4.5:1を余裕で満たす。
:root[data-theme="dark"] {
--text-high: rgba(255,255,255,.87); /* 見出し・本文 */
--text-medium: rgba(255,255,255,.60); /* 補助・キャプション */
--text-disabled: rgba(255,255,255,.38); /* 無効状態 */
--text-body: #E6E6E6; /* ベタが要る場面のオフホワイト */
}
body { background:#121212; color:var(--text-high); }
.caption { color:var(--text-medium); }
アクセント色のダーク再調整と、影/境界の代替。グローで標高表現はしない(Material非推奨)。
:root[data-theme="dark"] {
--primary: #B39DDB; /* not #6200EE。明トーン(~tone200)でAA 4.5:1を狙う */
--shadow-color: 220deg 60% 50%;
}
.card {
border: 1px solid rgba(255,255,255,.08); /* 影が見えない時の境界補強 */
box-shadow:
0 1px 2px hsl(var(--shadow-color) / .2),
0 2px 4px hsl(var(--shadow-color) / .2),
0 4px 8px hsl(var(--shadow-color) / .2);
}
/* color-mix が使えるモダン環境ならトークン生成も1行 */
.surface-3 { background: color-mix(in srgb, #121212, white 8%); }
チェックリスト
- 背景に純黒 #000000 を使っていない(基準は #121212)
- カード/モーダルの奥行きを黒い影ではなく「面の明るさ」で出している
- 積層したレイヤーは上に行くほど明るい(+4〜8%の明度ランプ)
- アクセント/ブランド色を彩度を落とした明トーン(~tone200)へ再調整した
- CTA・リンク・本文の主要な色で WCAG AA 4.5:1 を実測で確認した
- 本文に純白ベタを使わず、白の不透明度 87/60/38% で階層化した
- 影を使う箇所は黒の流用でなく色付き多層、または 1px ヘアラインにした
- グロー(発光)で標高を表現していない(Material 非推奨)
- color-mix / OKLCH を使う場合、レガシー環境向けに固定hexのフォールバックを併記した
限界 / 出典
primaryDark theme — Material Design (M2)
primaryapplyElevationOverlayColor — Flutter material API
primaryElevation — Atlassian Design
secondaryDark Theme with MDC — Chris Banes (Android Developers)
secondaryDesign for the Dark Theme — Snapp Mobile
blogDesigning Beautiful Shadows in CSS — Josh W. Comeau
bloggood dark mode shadows & elevation — parker.mov
blogDark Mode Color Design — ColorArchive
blogDesigning a Scalable and Accessible Dark Theme — fourzerothree