RGB vs HSL vs OKLCH — どのカラー空間で色を指定すべきか
CSS / デザインツール / 画像処理で使う 3 種類のカラー空間を、知覚均一性・補間品質・実装可能性で比較。CSS Color Module 4 で OKLCH が推されている理由も解説します。
何で選び分けるか — 知覚均一性・補間・指定しやすさ
カラー空間の選び方も「最新が常に正解」ではなく、4 軸で評価するのが現実的です。知覚均一性 (perceptual uniformity) は「数値上の距離」と「人間の目に映る色の差」が一致するかどうか。RGB と HSL はこれが揃わず、OKLCH はかなり揃います。補間品質 はグラデーションや color-mix() の中間色が綺麗に出るかで、知覚均一性とほぼ等価の話です。指定のしやすさ はデザイナー・エンジニアが頭の中で目的の色を組み立てられるか — #ff8800 を見てオレンジだと当てられる人はほぼいませんが、hsl(30, 100%, 50%) なら「色相 30°、ビビッド」と分かります。色域 (gamut) は sRGB に収まるか、Display P3 のような広色域を活かせるかで、ブランドカラーや写真の鮮やかさに直結します。
CSS Color Module Level 4 が OKLCH を採用したことで、2024 年以降は Tailwind v4 / Linear / Vercel / GitHub などのデザインシステムが OKLCH ベースのトークンに移行しています。とはいえデザインソフト・既存のデザイントークン・古い CMS は当面 HEX / RGB が中心なので、現場では 3 つを併用することになります。
3 カラー空間の比較表
| 項目 | RGB (sRGB) | HSL | OKLCH |
|---|---|---|---|
| 軸 | R (赤) / G (緑) / B (青) | H (色相) / S (彩度) / L (明度) | L (明度) / C (彩度) / H (色相) |
| 数値の意味 | デバイス出力に直結 | 人間の感覚に近いが線形ではない | 人間の知覚に対して線形 |
| 知覚均一性 | × (明度差が直感に合わない) | △ (色相をまたぐとくすむ) | ◯ (Oklab 由来) |
| 補間品質 | くすんだ灰色を経由しがち | 色相内は綺麗、色相間は中間がくすむ | 滑らかで彩度を保つ |
| 色域 | sRGB のみ | sRGB のみ (CSS の hsl は sRGB) | sRGB を超える (Display P3 等を指定可能) |
| 標準 | CSS 1 (1996) | CSS3 Color (2003 草案) | CSS Color Module 4 (2022) |
| 対応ブラウザ | 全て | ほぼ全て | Chrome 111+ / Safari 15.4+ / Firefox 113+ |
| 書式例 | #ff8800 / rgb(255 136 0) | hsl(32 100% 50%) | oklch(0.75 0.18 50) |
| 主な用途 | デザイントークン互換、コードからの直接指定 | デザイナーが手で組む UI パレット | パレット生成、グラデーション、color-mix() |
OKLCH の優位は数字で説明できます。HSL で「hsl(0 100% 50%) 真っ赤」と「hsl(60 100% 50%) 黄」を補間すると、CSS は中間で hsl(30 100% 50%) を返しますが、人間の目には「赤 → 黄」の中間が一度くすんで見えます。同じ補間を OKLCH で行うと、L (明度) と C (彩度) がほぼ保たれたまま H (色相) だけが回転するので、中間色がオレンジとして自然に立ち上がります。RGB 補間は最悪で、rgb(255 0 0) と rgb(0 255 0) の中点 rgb(127 127 0) が暗い黄土色になり、グラデーションの真ん中で「灰色っぽい帯」が出ます。CSS の color-mix(in oklch, red, yellow) が in srgb より見栄えがいいのは、この線形性の差が理由です。
ユースケース別の使い分け
既存のデザイントークン・ブランドガイドラインと整合させる: HEX / RGB。#1A73E8 のような社内標準色がすでに HEX で定義されているなら、無理に OKLCH へ書き換える必要はありません。レンダリングは同じ sRGB に落ちるので、表示上は完全に一致します。
「同じ明度で色相だけ違う」パレットを作る: OKLCH。L を固定して H を 12 色等分すれば、見た目で明度が揃ったカラーホイールができます。HSL で同じことをすると、青や紫が暗く、黄や緑が明るく見えるパレットになります。Tailwind v4 が --color-blue-500 等を OKLCH で定義しているのは、blue-500 / red-500 / green-500 の明度を見た目で揃えるためです。
グラデーションを設計する: OKLCH。linear-gradient(in oklch, red, blue) のように in <colorspace> を指定すると、中間色のくすみを抑えられます。in oklab / in lab / in hsl longer hue などの選択肢があり、それぞれ補間の経路が変わります。
Display P3 / 広色域: OKLCH。oklch(0.7 0.3 30) のように sRGB 外の鮮やかさを指定でき、対応デバイスでは sRGB に丸めずに本来の彩度で表示されます。color(display-p3 ...) と組み合わせるユースケースとも親和します。
コントラスト比の手計算・WCAG 検証: RGB から sRGB の輝度を出す式が WCAG 2.x の基準なので、計算の根拠としては RGB が便利です。L (明度) で揃えたつもりでも WCAG 上は微妙にズレることがあるので、配色決定後に color-contrast-checker で実値を確認する習慣を付けます。
ブラウザ内で相互変換とパレット設計
カラー空間の選択が決まっても、デザインソフトや既存ファイルから出てきた値は別表現であることがほとんどです。color-converter は HEX / RGB / HSL / HSV / OKLCH / Lab を相互変換し、指定の値を入力すれば他の表現が即座に出ます。#ff8800 を OKLCH に翻訳して oklch(0.74 0.17 50) を得る、HSL で組んだパレットを OKLCH 表現で書き出し直す、といった日常的な作業に向きます。配色の検証には color-contrast-checker、近似色の探索には color-blend を組み合わせるとひと通りの設計フローが手元で完結します。
注意点は OKLCH の値はディスプレイの色域に依存して見え方が変わる ことです。Display P3 対応の MacBook で oklch(0.7 0.3 30) がビビッドに見えても、sRGB の旧モニタでは色域の境界で丸められて彩度が落ちます。最終出力先のディスプレイ環境を仮定して値を決める必要があり、可能なら対象デバイスでの実機確認が安全です。ツールはすべてブラウザ内の Canvas / CSS Color パーサで動いており、入力した色情報をサーバーへ送る経路はありません。実装は GitHub で公開しており、DevTools の Network タブで送信ゼロを目視確認できます。