OKLCHカラーとは何か
(jakub.kr)- OKLCH は 人間の視覚認知に合わせた最新のカラーモデル で、色同士の 明るさ・彩度・色相の変化が均一に感じられる特性 を持つ 知覚的に均等なカラーモデル
- 構造は Lightness(明るさ)、Chroma(彩度)、Hue(色相) で構成され、既存モデルに比べて 一貫したカラーパレットの構成 が可能
- 同じ明るさ・彩度を保ったまま Hueだけを変更 しても均一な色パレットを作れるため、UIデザインに有利
- sRGB/HSLと比べて 予測しやすい明暗変化と均一なグラデーション を提供するが、場合によっては意図しない色が生成されることもある
- Display-P3のような最新ディスプレイ ではより広い色表現が可能で、最新ブラウザでは CSS Color 4 としてサポートされ、sRGBフォールバック処理 も提供されているため、徐々にWeb標準として定着しつつある
OKLCHカラーモデルの紹介
- OKLCHは 知覚的均一性(perceptually uniform) を目的に開発された最新のカラーモデル
- このモデルは 人が実際に色を認識する方法 に近い形で動作するため、デジタルデザインやフロントエンド開発で 色の扱いがはるかに容易になる
カラーモデルの基本概念
- カラーモデル は色を数学的に定義し表現する システム
- 主に使われるモデルの例: RGB, HSL, LCH, OKLCH, LAB, XYZ
- それぞれのモデルは 色表現および操作のしやすさ を左右する
色の表記方法の例
- oklch(0.55 0.18 260)
- hsl(220 100% 50%)
- rgb(0, 128, 255)
- lch(60% 60 260)
- lab(50 -10 -50)
- color(xyz 0.18 0.19 0.6)
- #1E90FF
Gamut(色空間の範囲)
- Gamut はそのカラーモデルが表現できる 色全体の範囲 を意味する
- 代表的なgamut: sRGB(Webの標準)、Display-P3(最新デバイスで対応)
- 色空間は gamutの範囲 に加えて、white point、transfer function などさまざまな属性を持つ
OKLCHの構造
OKLCHとLCHはどちらも Lightness、Chroma、Hue という3つの値で構成される
OKLCHは OKLab 色空間を基盤としている
- Lightness(明度/明るさ) : 0〜1 または 0%〜100% で表現され、明るさの均一な変化 を保証する
- Chroma(彩度) : 色の強さで、HSLの Saturation(彩度) に似ている
- Hue(色相) : 0〜360度の角度で色を表す
OKLCHの利点と活用
-
一貫した明るさ
- OKLCHでは 同じ明るさと彩度の値でhueだけを変えて 色を指定すると、すべての色が似た明るさに感じられる
- 従来のsRGBやHSLでは、色によって明るさや彩度が一貫して見えないことがある
- そのためOKLCHは 知覚的に均等なカラーパレット を作りやすい
-
予測しやすい色の明度ステップ
- OKLCHで 明るさを変化させると、hue(色相)やchroma(彩度)を変えずに 多様な色の段階を作ることができる
- HSLなどでは明るさが変わると色相がずれるドリフト現象が起こる
- OKLCHでは明るさだけを調整しても一貫した色の明度ステップを作成できる
-
グラデーション(Gradients)の扱い方
- sRGBでは 赤・緑・青の値の間を補間 するため、中間地点が濁ったり明るさの変化が激しくなったりする
- OKLCHは Lightness、Chroma、Hue軸に沿って補間 するため、より自然なグラデーションを実現できる
- ただし Hue値が円環構造 のため、予期しない色の変化が生じることがある
- これを防ぐには、OKLabで直線補間(interpolation)することでより予測しやすい結果を得られる
色空間のサポート
- sRGBでは最新ディスプレイが表現する広い色空間の一部をカバーできない
- OKLCHを使えば Display-P3など広い色域に対応する機器でより鮮やかな色表現が可能
- sRGBしか対応しない機器では できるだけ近い色にマッピング される
最大Chroma(彩度)値
- OKLCHでは実際のスクリーンが表現できる範囲外の色も数学的には指定できる
- たとえば
oklch(0.7 0.4 40)のように大きすぎるchroma値は実際には表示できず、近い色にクリッピング される - 最大chromaの概念 を理解し、色味、明るさ、選択する色空間(sRGB、Display-P3)に応じて適切な値を設定することが重要
ブラウザ対応とフォールバック
- OKLCHカラーは CSS Color Module Level 4 で導入され、最新ブラウザの大半でサポートされている
- 古いブラウザでは対応していない場合があるため、@supports CSSディレクティブでフォールバック値を設定できる
@layer base { :root { /* sRGB hex */ --color-gray-100: #fcfcfc; --color-gray-200: #fafafa; --color-gray-300: #f4f4f4; @supports (color: oklch(0 0 0)) { /* OKLCH */ --color-gray-100: oklch(0.991 0 0); --color-gray-200: oklch(0.982 0 0); --color-gray-300: oklch(0.955 0 0); } } } - 対応ブラウザではOKLCH、非対応ブラウザではsRGB(hex)の色が適用される
oklch.fyiツール
- oklch.fyi はOKLCHカラーパレット生成、CSS変数変換など OKLCH関連機能 を提供するWebツール
- デザインシステムやテーマ開発などでOKLCHカラーの活用を容易にしてくれる
1件のコメント
Hacker News のコメント
「Better Gradients」という機能には疑問がある。OKLCH は極座標空間で、この空間では Hue は角度として機能する。異なる 2 点の色を補間するときは、円の縁に沿って移動することになる。たとえば
linear-gradient(in oklch, #f0f, #0f0)というコードを書くと、緑から紫へつながる間に、目立つ形で色域外へ出てしまう。逆方向に円を回すと、linear-gradient(in oklch longer hue, #f0f, #0f0)のように、青緑やアクアを通過する。こうした経路は、知覚ベースの色空間が sRGB や人間が知覚可能な色の領域、つまり Gamut の端を扱ううえで本当に扱いづらいことを示している。実際、値がほんの少し違うだけで色域外になる。これを解決するアルゴリズムはいろいろあるが、知覚的な均一性は犠牲になる。たとえばグラデーション上の赤が不自然に暗くなる。もしより良いグラデーションが欲しくて、知覚的均一性が重要なら、実際には Oklab 補間がデフォルトであるべきだ。Oklab は円を横切る直線経路で補間し、必要ならグレーも通る(linear-gradient(in oklab, #f0f, #0f0))。この方法なら、よく見かける sRGB 補間の暗くなる現象も避けられ、magenta から lime まで自然なグラデーションになる。ちなみに Tailwind v4 はベータ版では sRGB の代わりに Oklch を使っていたが、正式リリースではより安全なデフォルトとして Oklab を選んだブラウザで sRGB で色を補間する方法は、実際ほとんどバグのようなものだと思う。sRGB は対数スケールのエンコーディングなので、本来仕様上は sRGB で直接色補間せず、線形 RGB に変換してから補間すべきだ
この記事は修正されたので、私のコメントは無視して構わない。それでも Oklab 補間をデフォルトにすべきだという点には同意する。記事でも「より良いグラデーション」について、OKLCH の hue が円形なので予想外の経路をたどることがあると書いていた。こうした問題を避けるために多くのツールが OKLAB を使っており、Oklab は直線経路で一貫した結果を与えるとしている
実際、CIE LAB も同じ役割を果たし、しかも標準としてすでに存在している(CIE LAB Wikipedia)
W3C の検討資料
とても有益な説明をありがとう。この記事を書いた本人です。もっと明確に説明できるよう内容を修正します
スペクトルの反対側にある 2 色でグラデーションを作るのは、やや極端なケースだ。どう見えるべきかに正解もないし、実際のデザインでそんなグラデーションが必要になることもまれだと思う。普通はデザインでグラデーションを使うとき、中間色を自分で選ぶことになる
OKLCH に関しては、oklch.com が直感をつかむのに役立った。ただし hue 値は HSL の hue とは異なり、hue と lightness ごとに chroma の最大値が変わる点には注意が必要だ。これはバグではなく、人間の目とディスプレイ特性を反映したものだ。HSL と違って、HSL は最大値が常に一定だが、色の意味は一貫していない。CSS の OKLCH の良いところは、数式の形で操作できることだ。たとえば
oklch(from var(--accent) calc(l + .1) c h)のように書ける。ただ実際に数式をうまく使うには、色彩理論が必要か、テストしてみる必要がある。たとえば影は単純に lightness だけ変えればよいと思っていたが、実際には hue も変える必要がある。OKLCH グラデーションが常に最良というわけではない。近い hue を使うと色が均一に見えやすいが、実際に光が混ざるとき物理的にどう変化するかまで気にするなら XYZ 色空間が必要だ。関連して MDN color-mix ドキュメント が参考になる。ちなみに「ok」は本当に単に OK という言葉に由来する。意味としては、従来の LCH に問題があった(OK ではなかった)ことに由来しているCSS の OKLCH で数式が使えるのが良いと言ったが、実は相対カラー操作はすべての CSS 色空間で使える。たとえば
background-color: rgb(from var(--base-color) calc(r - 76.5) g calc(b + 76.5));のように使えるOKLCH と相対カラーのおかげで、スタイルシートにハードコードする色の数を大幅に減らせた
サンプル CSS 変数
いくつかの批判点はすでに挙げられているが、OKLCH と CSS での適用方法の紹介としてはかなり良い記事だと思う。補足的な疑問として、最近ブログ記事に日付を表示しないトレンドがあるのか気になった。特に「OKLCH は新しい色モデルだ」という文句は、今後すぐ古びていくと思う。メインサイトには「2025年8月」とだけ書かれていて、日付表記を意図的に避けているように感じる
関連サイト
うまく説明はできないが、日付のない記事は深刻な問題だと思う。これが最近のトレンドなのかは分からないが、日付がないといくらでも昔の記事だと勘違いできてしまう。たまにコメントに残っているタイムスタンプから記事の年を推測するが、そもそもコメント機能すらないブログも多く、再訪したい気持ちが薄れる。(OP のメインページには「細部にこだわらない」と書いてあるのに、デザイン美学にはこだわって機能性を落としているのが皮肉だ)
記事に日付がない場合、私は HTTP で HTML 文書を取得するとき
Last-Modifiedヘッダーを見るようにしている。ただ、著者が日付を気にしていないことも多い。ブログという言葉からも分かるように、本来は [web]-log としてタイムスタンプが中核要素であることを理解していないように思える。ちなみにLast-Modifiedの値は、そのリソース(HTML)の最終更新時刻を示す。サーバーがキャッシュ構成をしておらず、バックエンドで毎回再レンダリングしていると、日付が常に更新される現象が起きるこの問題の例
古いコンテンツが検索エンジンで順位を落とすのを防ごうとする SEO 目的が大きい。実に面倒な小細工だ
Google と SEO のせいだ
OKLCH 色が HSL と比べて一貫した青を与えると言っていたが、実際には OKLCH の明度変化はかなり緑寄りに移動する。知覚的な強度を一定に保てるのは確かな利点だが、ここで主張されている効果は誇張されているように感じる
この色の Hue チャートを見ると理由が分かる
OKLCH 色チャート
明度を上げるとその色の Hue バンドの限界を超え、ディスプレイ上で再現可能な明るい青の限界のため、色が Cyan(シアン)寄りに移動する。OKLCH はグラデーションで明度を調整するとき、Hue 不変ではなく Saturation 不変だ。この効果が良いかどうかは美的な好みの問題だが、長いあいだ Hue が一定で desaturated な Web カラーばかり使ってきたので、「どちらの妥協点を選ぶかを選択できる」という点が新鮮だ
関連する Hacker News 議論
近年は科学界でより深い青色 LED も発明されているので、10〜20 年後に Display P3 を置き換える技術が現れれば、このような Cyan シフトなしに、より正確な青のグラデーションを表現できるようになるのではと期待している。それまでは、デザインとして見栄えが良いことが正解だ。
ちなみに今後の色空間設計では、Hue と Saturation を必ずしも二者択一にするのではなく、ディスプレイの限界までは Saturation 不変、限界点では徐々に Hue 不変へ移行するような方法も考えられるかもしれない。ただしこれは色プロファイル(IDCv4)の制約上、非常に難しい。それでも実験的な DisplayCAL ターゲットとしては面白そうだ
私のディスプレイでは、例で green shift はまったく見えない。もしかすると画面のキャリブレーションが合っていないのではないかと思う
同意する。色が完全に青からシアンに変わっている。もし OKLCH がこれで正しく実装されているのなら、私は絶対に使いたくない。hue 計算に何か深刻な問題があるように見える。HSL/HSV は知覚的 lightness に問題があるが、hue 自体は常に一定なので補正は不要だ
色彩科学には詳しくなく主観的な意見かもしれないが、OKLCH 色の右端は最悪でも blue-green(青緑)か、せいぜい light blue(薄い青)程度に感じる。一方で、HSL の最も明るい側の 2 色は blue には見えず、むしろ右から 2 番目は light purple(薄紫)、いちばん右はほとんどグレーに見える。キャプションでは HSL の暗い側が grayish だとしていたが、実際には OKLCH でも HSL でも leftmost(最も暗い側)は青っぽく見える。macOS Digital Color Meter で測ると、右端の OKLCH と HSL はどちらも green 値がほぼ同じだ(226 と 227、sRGB では 228 と 227)
この話題については、もっと良い記事を勧めたい
Evil Martians の OKLCH in CSS: Why quit RGB, HSL 記事
試せる OKLCH 変換ツール
以前の Hacker News 議論(6か月前、コメント 30 件)
OKLCH は OKLab(知覚ベースの均一色空間)を基に作られたもので、Lightness(明度)、Chroma(彩度)、Hue(色相)を調整するモデルだ。「OK」は、作者が「まあまあうまく動く」と答えたことに由来する名称だ
色やテキスト/ロゴの作業では、コントラストと可読性も必ず考慮すべきだと思う
APCA Contrast
コントラストチェック(WCAG 2)
そのほかにもさまざまなツールがある
私の頭の中では OKLCH という名前が "Oklachroma" と自然に解釈されていた
OKLab 色空間を紹介した最初のブログ記事があり、歴史的観点から興味深い
OKLab の元記事
なぜ OKLCH 色空間への変換式が文書化されていないのか気になる。ググってみると Gist が 1 つあるだけで[0]、Oklab についての Wikipedia はある[1]
Gist の変換式の例
Oklab Wikipedia
変換の核心は Oklab と sRGB の間の行列にある。OKLab-OKLCH 変換そのものは単なる座標変換で、Wikipedia にも載っている
OKLCH と OKLab は同じ色空間だ。ただ、直交座標(OKLab)と極座標(OKLCH)で表現方法が違うだけだ