
カラーパレットのコントラスト比を揃えるのにOKLCHカラースペースが便利だった
株式会社アンドパッドでUIデザイナーをしている、よつくらです。
2024年の7月、おそらく3年ぶりにアンドパッドで運用しているデザインシステムの、網羅的なカラーパレットを作成しなおしました。今回、カラーパレットのコントラスト比を揃えるのにOKLCHカラースペースが便利だったので紹介します。
網羅的なカラーパレットのコントラスト比を揃える
前回カラーパレットを作成したとき、1段階目の網羅的なカラーパレットと、2段階目の意味を持ったカラーパレットを作成しました。そのときの学びは下記のnoteにまとまっています。
1段階目の網羅的なカラーパレットについて、色相の異なる色同士で同じコントラスト比を保っておいた方が、UIコンポーネントを作成するときに便利です。

例えば上の図のように、いろいろな色で使えるタグコンポーネントを設計するときのことを考えてみましょう。
この例では、青いタグを設計するときはOutlineにblue40、Labelにblue60という色を使っています。オレンジのタグを設計するときはコントラスト比がうまくとれなかったため、Outlineにorange70、orange80という色を使ってしまいました。青とオレンジで異なる強さの色を採用してしまったため、次に別の色のコンポーネントを足すときも毎回色の計算をする必要があり、面倒で、デザイナー間で計算方法を共有する必要もあります。
カラーパレットのコントラスト比を揃える
この問題を回避するには、網羅的なカラーパレットで色相がことなっていてもコントラスト比が一定になるように設計すると、とても便利です。

私が知っている範囲では、Goldman Sachsのデザインシステムがこのアプローチを採用しており、非常に合理的だと思いました(=変化に強いデザインシステムになる)。ただ、とても残念なのですがGoldman Sachsのデザインシステムは現在公開を停止しているようです…。どなたか公開されているURLを知っていたら教えてください。
HSLを使ったカラーパレット作成の弱点
では、色同士のコントラスト比を保つためにどのようなカラーモデルが使えるでしょうか?Figmaでは、HEX / RGB / HSL / HSB といったカラーモデルが利用できます。
【参考サイト: Figma Learn, Figmaデザインでのカラーモデル】
https://help.figma.com/hc/ja/articles/360043042113-Figmaデザインでのカラーモデル
HEX / RGB は、赤/緑/青の色のかけ合わせで色を記載するので、コントラスト比を一定にすることには向いていません。
HSL / HSB について、HSLを例にとると
Hue (色相)、Satuation (彩度)、Luminance (輝度)もまた、人の目がどのように色を認識するかに基づいたカラーモデル
と、記載されています。しかし、実はHSL/HSBカラーモデルは異なる色相同士のコントラスト比を一定にはしてくれません。
実験してみましょう。下のカラーパレットは、HSLの値を機械的に入力して作成したカラーパレットです。異なる色相間でコントラスト比はどうなっているでしょうか…?

同じカラーパレットをPhotoshopでグレースケールに変換してみたものです。

一目見て分かるとおり、Hue50(黄色)やHue110(緑)の色域で明るい色になっており、その他の色域で暗い色になっています。また、WCAG2.2の基準でコントラスト比を計算してみると、HSLの値は機械的に決めたのにも関わらず、青色では基準を満たすが黄色では基準を満たさない、といったことがよく発生します。例えば一番暗い色でコントラスト比を計算すると、同じLightnessの値を使っているのにも関わらず #ffffff の色に対するコントラスト比が1:16〜1:18までバラバラになっています。

OKLCHカラースペースについて
OKLCHカラースペースで、先程HSLカラーモデルでやってみたように機械的にカラーパレットを作成してみましょう。

Hue98とHue140の明るい色が、他の色域と比べて明るく濃い色になっていますが、これは見間違いではなくOKLCH上でもChroma(Saturationとは異なる)の値が高くでてしまう色域です。このChromaの量は、コントラスト比は一定のまま増減できるので、実際にUIデザインに使うカラーパレットを設計するときはChromaの量の調整が必要です。
また、これを先ほどと同様にPhotoshopでグレースケールに変換します。

いかがでしょう。HSLカラーモデルより明らかにコントラスト比が一定の割合で変化していることが分かるかと思います。これは数値上も正しく、WCAG2.2の基準で計算しても使用できる色数と、各階層のコントラスト比は変わりません。

OKLCHカラースペースのモデル
OKLCHカラースペースは、下記の画像のように色相ごとに異なるLightnessとChromaのカーブを持っています。それを実際に利用するときにはHSL色空間のように円筒状に利用できるようにマッピングしてくれます。

これは下記のOKLCHカラースペースを計算してくれるツールの3Dグラフをグリグリと動かすと、直感的に理解できるので、試してみることをおすすめします。

OKLCHカラースペースはすでにCSS仕様に採択されている
OKLCHカラースペースは、実はすでにCSS仕様に追加されており、2023年以降のブラウザで下記のような記法で記述できます。
oklch(12.3% 0.123 12.34)
ここまで普及した色空間ですので、カラーパレットを設計した本人以外でもパラメーターさえ分ければ気軽に変更することができ、デザインシステムを継続してエンハンスすることができます(=色を設計した本人に依存せず、チームで運用することが可能)。
また、すでにツールも充足しているため、特定のカラーピッカーツールに依存することなく運用することができます。
OKLCHカラースペースの歴史(私調べ)
OKLCHカラースペースは、下記のような順序で生み出されたもののようです。(私調べ。もっと詳しい方いたら正しい情報を教えてください🙇♂️)
1976年、CIEが上記のような色空間の問題を解決するために「CIELAB色空間」を定義。
2019年、LEA VEROUさんがLCH色空間を設計
https://lea.verou.me/blog/2020/04/lch-colors-in-css-what-why-and-how/
LCH色空間は、利用者が操作するパラメーターはOKLCHと同じで利用しやすいのですが、生成される色が色相が同じ色に見えない(グラデーションがかかっているように見える)問題がありました。
Björn Ottossonさんが、CIELAB色空間が優れているにもかかわらずあまり使用されていないこと、LCH色空間の特に青色が均一に見えない問題に気づき、OKLAB色空間とOKLCH色空間を定義
具体的には、色相ごとに異なる山型を持つCIELAB色空間を、HSL色空間のように色相を円とした円筒状に再マッピングした。
個人でこんなこと出来るんですね。すごい。
最後に
このようにOKLCHカラースペースを使うと、異なる色相間で一定のコントラスト比を保ったまま網羅的なカラーパレットを作成することができます。
一方、黄色〜オレンジの色域ではやはりパキっとした色を作ることは難しく、これを解消するにはWCAG3.0で検討されている、新しいコントラスト比の計算を待たなければならないかな、と思っています。
今のOKLCHカラースペースの範囲内でオレンジや黄色をきれいに見せる方法についてもある程度検討したので、気になる方は私や私のX(Twitter)で聞いてみてください。
私と同じように色相間でコントラスト比を揃えることを検討している方は、ぜひOKLCHカラースペースを使ってみてください。