世界を動かす技術を、日本語で。

OKLCHカラーとは何ですか?

概要

  • OKLCH は人間の視覚に基づいた 新しいカラーモデル
  • 他のカラーモデル(RGB, HSL, LCH等)との 違いと利点 を解説
  • ガンマット やカラースペースの基礎知識
  • 一貫した 明度・色合い の調整やグラデーション作成が容易
  • CSSでの利用方法 やブラウザ対応・フォールバックも紹介

OKLCHとは何か

  • OKLCH知覚的均一性 を重視した新しいカラーモデル
  • 色を 人間の目の感覚 に合わせて表現
  • 色操作や配色設計が 直感的 になるメリット
  • RGB、HSL、LCH など従来モデルとの比較
  • 色モデルは色を 数値や構造 で表現するための仕組み

ガンマットとカラースペースの基礎

  • ガンマット は各カラーモデルで表現可能な 色域
  • 代表的なガンマット: sRGB (Web標準)、 Display-P3 (最新デバイス用)
  • カラースペースは ガンマット だけでなく ホワイトポイントや伝達関数 も定義
  • 詳細は省略し、基本のみ解説

OKLCHの構造

  • Lightness(明度) :0〜1または0%〜100%、 均等な明るさ変化
  • Chroma(彩度) :色の強さ、 彩度に近い概念
  • Hue(色相) :0〜360度で表現、 色合いの角度指定
  • LCHとOKLCHの違いは 基盤とするカラースペース (OKLabを利用)

一貫した明度・色合いの実現

  • 複数のボタン色を作る場合、 OKLCHならHueのみ変更で均一な印象
  • HSL等従来モデル では明るさや鮮やかさが 不均一 になりやすい
  • 視覚的に均一なカラーパレット 作成が容易

予測可能な色の階調

  • 明度値のみ変更 で一貫した色の階調作成が可能
  • 他モデルでは 色相や彩度がズレる 問題
  • 例:OKLCHなら青色の階調が一貫、HSLでは薄い色が紫に、暗い色が灰色に近づく

グラデーションの違い

  • sRGB ではRGB値で補間し、 中間色が濁りやすい
  • OKLCH ではLightness, Chroma, Hueで補間し、 均一なグラデーション
  • 始点と終点は同じでも 途中の色の見え方が大きく異なる

カラースペース対応

  • sRGB では表現できない色も OKLCH で記述可能
  • Display-P3 対応ディスプレイではより鮮やかな色
  • 非対応環境 では自動でsRGB内にマッピング
  • グレー系はsRGB/Display-P3で違いなし

最大Chroma値とガンマット外の色

  • OKLCH は理論上、実際のディスプレイで表現不可な色も指定可能
  • 例:oklch(0.7 0.4 40)は高Chroma値でガンマット外
  • ガンマット外の色は自動でクリッピング され、意図と異なる色になる場合あり
  • 最大Chroma値 の概念:Lightness, Hue, ガンマット(sRGB/Display-P3)に応じて最大値を計算

CSSでの利用とフォールバック

  • OKLCH はCSS Color Module Level 4で導入、 主要ブラウザで対応

  • 古いブラウザ では未対応な場合も

  • @supports ディレクティブでsRGBとのフォールバック指定可能

    • 例:
      • sRGB(hex)を初期値に
      • OKLCH対応時のみOKLCH値を上書き

OKLCHツールと情報

  • oklch.fyi :OKLCHカラーパレット生成やCSS変数変換ができるツール
  • 質問は jakub@kbo.sk まで
  • 追加情報は Twitter でも発信

Hackerたちの意見

「Better Gradients」ってちょっと怪しいよね。OKLCHは極座標空間なんだ。色相はこの空間での角度を表してるから、色相を一つの角度から別の角度に補間するには、円の端をぐるっと回る必要があるんだ。これが、例えばこんな極端な例を生むわけ:linear-gradient(in oklch, #f0f, #0f0)。逆回りに円を回ることもできて、そうすると青からアクアを経由することになる:linear-gradient(in oklch longer hue, #f0f, #0f0)。どちらの場合でも示されているグラデーションは、知覚色空間で作業するのがいかに難しいかの良い例だよ。ほぼ円の端をぐるっと回る間、sRGBの範囲外になっちゃうし、実際には人間が認識できる色の範囲を大きく超えてるんだ。知覚色空間は、ガマットの端を扱うのが本当に苦手で、値を少し変えるだけでガマットを外れちゃうんだ。だから、色をガマット内に戻すためのアルゴリズムが定義されてるけど(そう、複数あるよ:どのアプリケーションも使う技術に合意してるわけじゃないから)、それは知覚的均一性を犠牲にすることになる。あのグラデーションの赤は、他の部分よりもずっと暗いんだ。もしより良いグラデーションを探してるなら、知覚的均一性を気にするなら(実際にはあまり気にしない方がいいけど、知覚色空間は過剰に使われてるから)、Oklabで補間するのがいいと思うよ。これなら円の一方からもう一方へ直線で行けるから—必要なら灰色を通るけどね。linear-gradient(in oklab, #f0f, #0f0)。この場合、赤や黄色を経由せず、マゼンタからライムへのグラデーションがかなり良い感じになるよ。sRGBの補間による不適切な暗さも出ないし(…でも、もし手動でそのグラデーションを調整するなら、実際にはOklabより少し暗くするかな)。Tailwind v4のベータ期間中に、グラデーション補間をsRGBからOklchにシフトしようとしたけど、リリース時にはOklabが安全なデフォルトだと決めたみたい。

すごく興味深いね。これは今のハードウェアの限界なのかな?みんながフルDCI-P3の広いガマットモニターを持ってたら、この問題はどれくらい残るんだろう?それでもOKLCHのフルガマットには届かないけど、問題はほぼ消えるのかな?

他の人が開発ツールにグラデーションをコピー&ペーストして見るときのために: 二つ目の色の最初に#が抜けてるよ。それと、両方のoklchグラデーションはちょっと変だけど、oklabのグラデーションはいい感じに見えるよ(グレーを通るのを受け入れられるならね)。

OKLCH:OKLab(知覚的均一色空間)に基づいたカラーモデルで、明度、クロマ(彩度)、色相を制御できるんだ。「OK」は、創始者のビョルン・オットソンによると「まあまあの仕事をする」って意味だよ。

彼はスウェーデン人だから、実はOKは「オットソンの色」の略なんじゃないかな。でも、彼は謙虚なんだね。

色やテキスト/エンブレムを扱うときは、コントラストや可読性も考慮してね: https://apcacontrast.com/>

上記のサイトは、最新のコントラストアルゴリズムで測定するのに便利だけど(これはまだリリースされていないWCAG 3アクセシビリティ基準の現在のアルゴリズム)、WCAG 2のアルゴリズムは少し違うし、多くの市場/業界で法的要件になってることを忘れないでね。そのアルゴリズムに対して色をチェックするには、 https://www.siegemedia.com/contrast-ratio みたいなツールが使えるけど、他にもたくさんあるよ。

いい投稿だね。OKLCHはかなり便利だけど、CSSで色を書くときには、最終的にはOKHSL/OKHSV[1]の形が出てきてほしいな。そうすれば、ユーザーはガマットの境界を気にしなくて済むから。 [1] https://bottosson.github.io/posts/colorpicker/

他の人がすでに指摘しているいくつかの批判を除けば、これはOKLCHとCSSでの使い方の良い紹介だと思う。これを置いておいて、ちょっと脱線したいんだけど、ブログ記事に公開日を含めない現代のトレンドについて誰か説明してくれない?特にここで目立ったのは、冒頭の文で「OKLCHは新しいカラーモデルです」と言っていて、その「新しい」という部分は思ったより早く古くなるから。メインサイトには日付が書いてあるけど、「2025年8月」と限られてるから、これは意識的な選択のように見えるし、全然理解できない。 [0] https://jakub.kr/

誰か、ブログ記事に公開日を含めない現代のトレンドについて説明してくれない? そういう場合、私は通常、HTMLドキュメントにHTTPで提供されるLast-Modifiedヘッダーを見てみるんだけど、結局、コンテンツの日付を気にしない人たちが多いみたいで—彼らは「ブログ」という言葉がどこから来ているのか理解していると思うけど、"[web]-log"でタイムスタンプが重要なのに—そういう人たちはHTTPの仕組みも知らないし、気にもしないんだよね。ヒント: Last-Modifiedはそのリソースの最終更新時刻で、実際のHTMLドキュメントのこと。あなたの「バックエンド」がサーバーキャッシュを正しく設定しなかったからコンテンツを再レンダリングしたからって、毎日新しいコンテンツだと見せかける必要はないよ(残念ながら、https://jakub.kr/components/oklch-colorsはそうしてるから、HTTPからタイムスタンプがわからない)。

いい投稿だね!それと、oklch.comもチェックしてみて。直感をつかむのに役立ったよ。ちょっとしたつまずきがあって、色相はHSLの色相とは違うし、最大彩度も色相や明度によって異なるんだ。これはバグじゃなくて、人間の目とコンピュータの画面の特性を反映してるんだよね。HSLのように一貫した最大値があるわけじゃなくて、意味が不一致になることもあるし。CSSのOKLCHのもう一つすごいところは、数式で書けるってこと。例えば、oklch(from var(--accent) calc(l + .1) c h)みたいにね。ただ、数式を理解するには色彩理論か、ちょっといじってみる必要があるよ。プログラマーの直感が「影は明度の変化だけで、色相の変化じゃない」って嘘を教えてくれたし。あと、OKLCHのグラデーションは客観的に見て最高ってわけじゃなくて、常にカラフルって感じ。似たような色相で使うと、記事の例みたいに見栄えが良くなるけど、現実的じゃない。光の混ざり方を知りたいなら、実際にはXYZが必要だよ。もっと詳しくはここを見てね: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value.... あと、面白い事実だけど、「ok」はただの「ok」って意味なんだ。LCHはダメだったってことを暗に示してるね、バグがあったから。

このテーマについていい記事を見つけたよ: https://evilmartians.com/chronicles/oklch-in-css-why-quit-rg... それに、ここにあるピッカー/コンバーターも役立つよ: https://oklch.com/ ハッカーニュースでの議論はこちら: https://news.ycombinator.com/item?id=43073819 (6ヶ月前、30件のコメント)

カラースペースの比較についてだけど、変だね。2008年のモニターでもDisplay-P3とsRGBの紫色の違いが見えるのに、こんなに色域が広いとは思わなかった。ブラウザやOSレベルで色の変換があるのかな?(私のディストロ/デスクトップはデフォルトでcolormgrを有効にしてる)。

完全に間違ってるよ。最初のはoklch(0.65 0.20 300)を使ってて、sRGBの範囲内に収まってる。境界にも達してない。二つ目はoklch(0.65 0.28 300)を使ってて、P3やRec.2020の範囲を超えてる。最小限の修正としては、二つ目をoklch(0.65 0.2399 300)にしてP3の範囲内に収めて、デモがRec.2020対応の場合に少し歪まないようにするのがいいかな(必ずしも必要じゃないけど、望ましいと思う)。最初のは#a95eff (oklch(0.6447 0.2297 301.67))で、CSSのフォールバックだね。でも紫はデモには最悪の選択肢だよ—P3はそのあたりでsRGBに対して最も少ない差を加えるから、違いが一番小さくなる。赤か緑の方がいい選択だね。だから、より良いペアは右側にoklch(0.65 0.2977284 28)(P3のガマットの端にある明るい赤、sRGBの範囲外)と、左側に#f00(範囲外のときにCSSがマッピングするsRGB値)になるね。

この投稿ありがとう。ハッカーニュースはこういう学びの機会があって時々素晴らしいね。このモデルのことは聞いたことなかったけど、記事には感謝してる。

これを使ってみようとしたけど、実用的な理由で諦めたよ。HSLは明度に焦点を当てて、彩度を合わせるけど、OKHCLは違うやり方をしてる。彩度の部分を技術的な限界まで押し上げて、色相を無理やり合わせてるけど、私たちは彩度を直感的に理解できないんだ。OKHSLが出てくるのを待ってるんだけど、調整がもっと小さくて、意図におかしな変化をもたらさないと思う。どこか別の場所でこの話をしたことがあるよ: https://www.reddit.com/r/css/comments/1jv5f0r/hue_is_an_issu...