結論
プロは「グレー=無彩色」を捨てる。彩度0%(S 0%)のグレーは色温度ゼロで死んで濁って見えるので、ブランドに寄せた色相を低彩度(目安 S 10〜30%)で仕込み、真っ黒・真っ白を避けて8〜10段の階調を組む。最後は数値で固めず目で詰め、本文グレーだけは輝度コントラストでWCAG AA(白地4.5:1=#767676以下)を必ず実測する。
01 — 彩度0%を捨て、低彩度で色相を仕込む
hsl() の S=0% は純グレースケール、つまり色温度がない=濁り・無生命さの正体。ブランドに関連する色相を H で固定し、S を 10〜30% に抑えると、「灰色っぽい青(greyish blue)」ではなく「青みのある灰色(bluish grey)」になり、意図した tinted neutral として読める。クールは青寄り、ウォームは黄/オレンジ寄りに振る。
blogColor Formats in CSS — Josh W. Comeau
blogBook summary: Refactoring UI — sglavoie.com
02 — 真っ黒・真っ白を避け、8〜10段で組む
#000 は自然界にない不自然な黒で、画面が硬く安っぽくなる。最暗は「とても暗いグレー」から始め、最明はわずかにオフホワイトの背景までを一定刻みで上げる。3〜4段だと必ず「#2より暗く#3より明るい」が欲しくなるので8〜10段持つ。最暗=最も暗い文字色、最明=控えめな背景からアンカーを逆算する。
primaryBuilding Your Color Palette — Refactoring UI
03 — 端ほど彩度を上げ、くすみ過ぎは避ける
明度が50%から遠いシェード(とても暗い/とても明るい)ほど、同じ彩度では色が抜けて washed out に見える。最暗・最明の端ほど S を足して色を保つ。ただし全体はあくまで低彩度。S が 30% を超えると tint が強すぎて「ニュートラル」ではなく「くすんだ色」に転び、UIが薄汚れて見える。狙いは bluish grey であって greyish blue ではない。
blogBook summary: Refactoring UI — sglavoie.com
blogSaturation and Chroma in Design — ColorArchive
04 — グレーの温度はブランド色の逆に振る
完全無彩色のグレーを色の付いた背景に置くと浮く。ブランドの色温度を取り、グレーは反対方向(暖色ブランドなら寒色グレー、寒色ブランドならウォームグレー)へ少しだけ振ると、画面がまとまり高見えする。「ブランド色を足す」とは矛盾せず、量と方向を文脈で選ぶ話。下は寒色ブランド背景に置いたカード。
blogUnderstanding grays — Bootcamp (Medium)
05 — 影は灰色でなく「色相+低明度低彩度」で作る
box-shadow を灰色や純黒で置くと、洗い流したように浅く安っぽい影になる。要素の色相に hue を揃え、saturation と lightness を下げた tinted shadow を低い alpha で重ねると、自然で深い影になる。グレー濁り回避の典型的な応用。
blogDesigning Beautiful Shadows in CSS — Josh W. Comeau
06 — 本文グレーはWCAG AAを輝度で実測する
コントラストは色相ではなく明度(輝度)で決まる。色相を足したグレーでも、最終はこの輝度比でクランプする。白地・通常テキストで AA(4.5:1)を満たす最も明るいグレーは #767676。#777777 は 4.47:1 で不合格(切り上げ不可)。大文字(18px以上、または14px以上のbold)は 3:1 まで緩和され、見出しはより明るいグレーが使える。色相距離でなく必ず輝度比を測る。
primaryWebAIM: Contrast and Color Accessibility
実装スニペット
クール(寒色)ニュートラルランプ。色相を固定し、50%輝度から離れる両端ほど S を上げて washed out を防ぐ。
:root{
/* 青みのある灰色: H=220固定, S=8〜18%, 端ほどS↑ */
--gray-50: hsl(220 16% 98%); /* オフホワイト背景 */
--gray-100: hsl(220 14% 95%);
--gray-200: hsl(220 13% 90%); /* border */
--gray-300: hsl(220 12% 82%);
--gray-400: hsl(220 11% 64%);
--gray-500: hsl(220 10% 46%); /* AA本文の境目付近 */
--gray-600: hsl(220 12% 36%);
--gray-700: hsl(220 14% 26%);
--gray-900: hsl(220 18% 14%); /* 最暗=純黒の代替 */
}
body{ color: var(--gray-900); background: var(--gray-50); }
ウォーム(暖色)ニュートラル。寒色ブランドの背景に当てると浮きが消える。S は最大でも20%程度に留める。
:root{
/* 黄みのある灰色: H=40, S=10〜20% */
--warm-50: hsl(40 20% 98%);
--warm-200: hsl(40 14% 89%); /* border */
--warm-500: hsl(40 8% 45%);
--warm-900: hsl(36 16% 13%); /* 最暗、純黒の代替 */
}
.card{ background:var(--warm-50); border:1px solid var(--warm-200); color:var(--warm-900); }
WCAG AA を満たすサブテキスト用グレー(白地)。色相を足したグレーでも最終はこの輝度比でクランプ。
/* 白(#fff)地・通常テキストで 4.5:1 を満たす最明グレー */
.text-muted{ color:#767676; } /* 4.5:1 = AA合格 */
/* NG: #777777 は 4.47:1 で不合格(切り上げ不可) */
/* 見出し(18px+ または 14px+ bold)は 3:1 まで緩和 → より明るくできる */
.heading-muted{ color:#949494; font-size:24px; }
tinted shadow。hue を要素に揃え、lightness を下げて alpha で重ねる。
.card{
/* 要素色相に合わせた青寄り・低明度低彩度の影を重ねる */
box-shadow:
0 1px 2px hsl(220 40% 20% / .08),
0 4px 12px hsl(220 40% 20% / .12);
}
/* NG: 0 4px 12px rgba(0,0,0,.15) → 灰色で浅く安っぽい */
チェックリスト
- グレーの `S` は 0% ではなく 10〜30% に入っているか(純グレースケールを排除したか)
- 色相 `H` はブランド色に関連づけたか(クール=青寄り/ウォーム=黄オレンジ寄り)
- `S` が 30% を超えて「くすんだ色」に転んでいないか(狙いは bluish grey)
- 最暗は `#000` でなく「とても暗いグレー」、最明は純白でなくオフホワイトか
- ランプは8〜10段あるか(バナー単発でも最低5段)
- 50%輝度から離れる両端ほど彩度を少し上げて washed out を防いだか
- 色の付いた背景に置くグレーは、ブランドの逆温度に振ったか
- 影は灰色/純黒でなく、要素色相に揃えた低明度低彩度の tinted shadow か
- 本文・サブテキストは白地で AA 4.5:1(`#767676`以下)を実機/ツールで実測したか
- 大文字・半透明重ね・白以外の背景は別計算でコントラストを取り直したか
- 初期値を出したあと、最後は数値でなく目で詰めたか(Trust your eyes, not the numbers)
限界 / 出典
primaryBuilding Your Color Palette — Refactoring UI
blogBook summary: Refactoring UI — sglavoie.com
primaryWebAIM: Contrast and Color Accessibility
blogDesigning Beautiful Shadows in CSS — Josh W. Comeau
blogColor Formats in CSS — Josh W. Comeau
blogUnderstanding grays — Bootcamp (Medium)
blogSaturation and Chroma in Design — ColorArchive
primaryTone-based Surfaces in Material 3
blogHow to Pick the Grays in Your Design System — Cortes Studio