O hirunewani blog

色空間とOKLCHを利用したカラーパレットの生成

Created at

CSSがサポートしている色空間の特性や歴史的な経緯、カラーパレットを生成する場合にOKLCH色空間の利用を推奨する理由について解説する。

CSSの色の指定方法には、sRGB色空間を利用するrgb()hsl()hwb()、CIELAB色空間を利用するlab()lch()、 Oklab色空間を利用するoklab()oklch()など様々な方法がある。

Webサービスを作成する際に、事前に用意されたカラーパレットを利用することが基本的には多いため、これらの価値を感じる機会はあまりないと思われるが、それぞれの色空間や指定方法には特性があり、機械的に色を生成する場合、どれを使うかによって異なる印象を与える。

この記事では、いくつかの色関数を利用したパレットの例と共に、その色空間の特性や歴史的な経緯を紹介し、最終的にOKLCH色空間の利用を推奨する。

HSLについて

hsl()は、sRGB空間におけるHue(色相)、Saturation(彩度)、Lightness(明度)を指定する。 rgb()と異なり色の三属性を元に指定できるため、パターンを作りやすい。

sRGB空間にはいくつか既知の問題がある。

  1. 国際電気標準会議(IEC)が定めたデバイスファーストな規格であり、様々なデバイスで再現できる色域のみであるため、色の表現に限界がある。
  2. 知覚均等性が低く、明度と彩度を固定にして色相を変えると、人間の知覚的に異なる明るさに感じられる。

これらの問題に対して、CIELAB色空間が登場した。

LCHについて

lch()は、CIELAB色空間におけるLightness(明度)、Chroma(彩度)、Hue(色相)を指定する。 CIELAB色空間は、国際照明委員会(CIE)が定めた色空間であり、人間が認識できるすべてのカラーを再現できるとされている。

しかし、CIELAB色空間はsRGB色空間に比べて知覚均等性に優れているが完全ではない上、次のような問題がある。

  • 彩度の均等性に問題があり、高彩度になると彩度の変化が認識しにくくなる。
  • 色相の直線性に問題があり、青系統の色相で彩度を下げていくと紫みがかった色になる。

これらの問題に対して、Oklab色空間が登場した。

OKLCHについて

Oklab色空間は、CIELAB色空間よりも知覚均等性に優れており、彩度の均等性や色相の直線性の問題も改善されている。

まとめ

oklab()oklch()は2020年に登場したばかりにも関わらず、既にほとんどのブラウザでサポートされている。

そのため現代では、ユーザーが定義した色などから複数色のパレットを生成するようなケースなどがあれば、知覚均等性に優れたOklab色空間を利用するといいだろう。

それ以外にも、自分でパレットを作りたいと思った際に、デザインに疎くてもOklab色空間を利用することで、よりバランスの取れたパレットを生成することが出来る。

パレットを生成する際の注意点

各色のバリアントが3種類程度の場合は、彩度を一旦固定して明度を変えるのでもいいが、多くのバリアントを生成する場合は、明度に合わせて彩度も変更しないと変化に乏しくキツすぎたり薄すぎるパレットが出来る。

明度を横軸、彩度を縦軸に取った正規分布のような値の取り方をすると、より一般的なパレットを生成することが出来る。

次の例は、彩度を固定化して生成している。

次の例は、正規分布に従って彩度を変化させている。

const l = 20 + i * 10;

const c = 0.13 * Math.exp(-0.5 * Math.pow((x - 50) / 20, 2));
const color = `oklch(${l}% ${c} ${h})`;

正規分布に従って変化させることで、彩度を固定した場合と比べて、より自然なパレットが生成される。

しかし、まだ違和感を感じるだろう。

一般的に綺麗だと認識されるパレットは、そもそも明度も均等には変化しなければ、彩度は明度に対して正規分布のような値の取り方をするが完全に正規分布に従うわけではなく、多くの場合、人の手によって絶妙な調整がされている。

OKLCHの章にあるパレットは、調整を行った明度と彩度を元に生成されている。