チュートリアル

CSSの色補間:なぜOKLCHが勝つのか

2分で読める

CSSが2つの色をブレンドするたびに(グラデーント内、color-mix()、またはトランジション内)、色補間を実行します。開始色と終了色の間の中間値を計算します。ウェブの歴史のほとんどの場合、その計算はsRGB色空間で発生しました。結果はしばしば淡く、飽和度が低く、または知覚的に不均一でした。最新のCSSでは、補間用の色空間を選択できるようになりました。選択は極めて重要で、OKLCHは一貫して最良の結果を生成します。

このチュートリアルでは、RGB補間が失敗する理由、HSLが不足しているところ、2024年以降のグラデーションと色ブレンディングのためにOKLCHが正しいデフォルトである理由を説明します。

RGB補間問題:淡いミッドポイント

色空間を指定しないでCSSグラデーントを記述する場合、ブラウザはsRGBで補間します。各ピクセルで、赤、緑、青のチャネル値を独立して直線的にブレンドすることにより、中間色を計算します。

これは合理的に思えますが、sRGBキューブの中央付近を通じて2つのエンドポイントが渡されると、悪く崩壊します。赤から緑へのグラデーションを考えてください。

/* デフォルト:sRGBで補間します */
background: linear-gradient(to right, #FF0000, #00FF00);

このグラデーントのsRGBのミッドポイントは#808000です。淡いオリーブ。数学的には、RGB 128、128、0はチャネル値の赤と緑の間で正確に中途です。しかし、知覚的に、2つの活発なプライマリの間の活発なミッドポイントのように見えません。グラデーションは淡い暗い谷を通じて下げます。他方が拡大する前に。

根本的な問題は、sRGBが知覚的に均一ではありません。 R、G、Bでの等しい数値的ステップは、認知された色または明るさでの等しいステップに対応しません。sRGBキューブは、人間のビジョンではなく、ディスプレイハードウェアのために設計されました。

/* sRGBを明示的に強制することができます */
background: linear-gradient(in srgb, red, blue);

/* またはレガシー構文(同じ結果) */
background: linear-gradient(red, blue);

両方は同じ脱飽和ミッドポイントを生成します。問題は構文ではなく、色空間自体です。

ガンマ問題

別の微妙性があります。sRGB値はガンマエンコードされています。生のsRGB値の0.5はディスプレイで放出された物理的な光の50%に対応しません。グラデーントの実際の知覚的なミッドポイントはガンマエンコード化されたsRGBではなく、直線の光で計算する必要があります。CSSレベル4が導入されましたin srgb-linearこれに対処するために:

background: linear-gradient(in srgb-linear, red, blue);

線形sRGBは、ガンマsRGBよりも明度遷移に優れています。しかし、それはまだ直角RGB空間であるため、色相シフト飽和低下問題を解決しません。

HSL色相シフト

HSLは、RGBへの人間読み取り可能な代替案として導入されました。その円筒形の表現(色相0~360角度、飽和度とライトネスのパーセンテージ)は、色関係について推論するのを容易にします。しかし、HSL補間には独自の特徴的な失敗モード:色相シフトがあります。

2つのHSL色の間を補間するとき、ブラウザは色合いサークルの最短円弧に沿って移動します。温かい赤(hsl(10, 100%, 50%))から涼しい青(hsl(220, 100%, 50%))に進む場合、最短パスは紫と紫を通じて渡されます。可能性がある場合と可能性がない場合があります。

しかし、より深い問題は、HSLのライトネスが知覚的に均一ではありません。 hsl(60, 100%, 50%)の黄色は、hsl(240, 100%, 50%)の青より劇的に明るく見えますが、L値を共有しています。黄色から青へHSLで補間するとき、認知された明るさは、一貫性のない方法で揺れ下げます。

/* HSLグラデーント—知覚的な明るさは色合い全体で不均一です */
background: linear-gradient(in hsl, hsl(60 100% 50%), hsl(240 100% 50%));

hsl(150, 100%, 50%)でのこのグラデーントのミッドポイントは、活発な緑色で、いずれのエンドポイントよりも知覚的に明るく見えます。グラデーションはスムーズに遷移するのではなく、中央でピークします。

HSL補間にはまた長い円弧の問題があります。色相角は360°でラップし、hsl(350, ...)(ほぼ赤)からhsl(20, ...)(オレンジ)へ補間する場合、HSLは短い方法ではなく、青、緑、黄色を通じた長い方法で色相サークルを旅することがあります。

OKLCH:一貫性と知覚的均一性

OKLCHは、Björn Ottossonが2020年に設計した、Oklabカラースペースのシリンドリカルフォームです。以前の色空間の知覚的均一性の不足に対処するため。その3つのチャネル(L明るさ、C色合い、H色相角)は、色相に関わらず、Lの等しい数値的変更が認知された明るさの等しい変更を生成するように調整されています。

2つのOKLCH色の間を補間するとき、以下を取得します。

  1. 遷移全体の一貫した知覚的明るさ。暗いミッドポイントへのたるみや明るいピークへの揺れはありません。
  2. 保持されたチロマ。ミッドポイントは、色相から独立してチロマが補間されるため、活発なままです。
  3. より短く、より直感的な色相パス。OKLCHの色相角は知覚的な順序で分布しているため、補間は期待される中間色相を通じて移動します。
/* OKLCH勾配—活発で、知覚的に均一 */
background: linear-gradient(in oklch, red, blue);

OKLCHの赤から青へのグラデーントは、活発なマゼンタと紫を通じて旅行します。知覚的に直感的なミッドポイント。それは飽和されたままで、全体を通じて均等に明るく。

サイドバイサイド比較

グラデーント ミッドポイント色 知覚品質
in srgb赤から緑へ #808000—淡いオリーブ 淡い、暗い谷
in hsl黄色から青へ 活発な緑色のピーク 不均一な明るさ、色スパイク
in oklch赤から緑へ 活発な温かい黄色 スムーズ、飽和、均一

自分でその違いを見るには、グラデーションジェネレーターを使用してください。異なる色空間でグラデーションをプレビューできます。

色をOKLCHに変換する方法

すべての色値をCSSで書き換える必要はありません。グラデーション上のin oklchフラグは、補間前にエンドポイント色をOKLCHに変換し、出力色空間に戻すようにブラウザに指示します。16進値を保持できます。

/* これらの16進エンドポイントはOKLCH補間のために自動的にOKLCHに変換されます */
background: linear-gradient(in oklch, #FF5733, #3498DB);

#FF5733はおおよそoklch(0.63 0.24 27)#3498DBはおおよそoklch(0.63 0.14 232)です。カラーコンバーターを使用して、グラデーション設計前に16進コード相当のOKLCH値を確認してください。補間が先行して何を移動するかについて予備知識があれば。

color-mix()関数

CSScolor-mix()は、宣言的なAPIで、2つの色をブレンドするためのもので、すべてのモダンブラウザで2023年から利用可能です。その構文は最初の引数として補間色空間を含みます:

color: color-mix(in oklch, #FF5733 50%, #3498DB);

これは#FF5733#3498DBをOKLCHスペースの等しい比率でブレンドします。結果は、淡いsRGB平均ではなく、2つの色の間の本物の知覚的なミッドポイントのような活発な中間値です。

実践的なcolor-mix()用途

透明なバリアント作成:

:root {
  --brand: #2563EB;
  --brand-10: color-mix(in oklch, var(--brand) 10%, transparent);
  --brand-20: color-mix(in oklch, var(--brand) 20%, transparent);
  --brand-50: color-mix(in oklch, var(--brand) 50%, transparent);
}

白または黒へのティントアップ:

:root {
  --brand: #2563EB;
  --brand-light: color-mix(in oklch, var(--brand) 70%, white);
  --brand-dark:  color-mix(in oklch, var(--brand) 70%, black);
}

これはシェードジェネレーターと同じ概念ですが、前処理なしで完全にCSSです。OKLCHでの結果は、白または黒に近づくにつれてチロマが適切に変わるため、HSLと同等の操作よりも自然に見えます。

ホバー状態派生:

.button {
  background: var(--brand);
}
.button:hover {
  background: color-mix(in oklch, var(--brand) 80%, black);
}

警告:sRGBcolor-mix()

in <colorspace>引数を省略すると、color-mix()はsRGB補間にデフォルトします。

/* これはsRGBを使用します—淡い結果を生成される可能性があります */
color: color-mix(#FF5733, #3498DB);

/* 正しい:スペースを指定します */
color: color-mix(in oklch, #FF5733, #3498DB);

常にin oklch(または別の好みの空間)を明示的に指定してください。デフォルトのsRGBは後方互換性のため保持されますが、ほとんど最良の選択肢です。

グラデーション補間色空間

モダンCSS構文では、方向キーワード後のin <colorspace>を使用して、グラデーション宣言内で補間色空間を直接指定するオプションがあります。

/* sRGB(デフォルト、しばしば淡い) */
background: linear-gradient(to right, red, blue);

/* 線形sRGB(より良い明度、まだ色相の問題がある) */
background: linear-gradient(in srgb-linear to right, red, blue);

/* HSL(色相シフト、不均一な明るさ) */
background: linear-gradient(in hsl to right, red, blue);

/* OKLCH(推奨:活発で、知覚的に均一) */
background: linear-gradient(in oklch to right, red, blue);

/* Oklab(また優れた、より少ない直感的な構文) */
background: linear-gradient(in oklab to right, red, blue);

この構文はすべてのグラデーションタイプに適用されます。linear-gradientradial-gradientconic-gradient

OKLCH内のセクシャル補間方向

色相補間については、色相サークルの周囲でのより短いまたはより長い円弧を移動するかどうかを制御できます。

/* より短い円弧(デフォルト) */
background: linear-gradient(in oklch, hsl(30 100% 50%), hsl(270 100% 50%));

/* より長い円弧—黄色、緑、シアンを通じて旅行してから紫へ */
background: linear-gradient(in oklch longer hue, hsl(30 100% 50%), hsl(270 100% 50%));

/* 色相角を増やす方向—常に進む方向に進みます */
background: linear-gradient(in oklch increasing hue, hsl(30 100% 50%), hsl(270 100% 50%));

shorter hueキーワード(デフォルト)はほとんどの場合、最も自然な結果を提供します。longer hueバリアントは、虹効果や、グラデーションが色相スペクトルの広い部分を移動したいときに役立ちます。

マルチストップグラデーション

OKLCH補間は、各セグメントが知覚的に活発なミッドポイントを補間するため、マルチストップグラデーントでさらに価値があります。

/* 虹グラデーション、全体を通じて活発なままです */
background: linear-gradient(
  in oklch to right,
  oklch(0.70 0.20 30),   /* orange-red */
  oklch(0.80 0.20 90),   /* yellow */
  oklch(0.75 0.20 150),  /* green */
  oklch(0.65 0.20 240),  /* blue */
  oklch(0.60 0.20 300)   /* purple */
);

L値とC値は知覚的に調整されるため、すべてのストップで同様の値に設定すると、sRGB虹で一般的な明度ディップなしで自然に明るく飽和した虹が生成されます。

ブラウザサポート

in <colorspace>グラデーント構文は、すべてのメジャーブラウザでサポートされています。

  • Chrome/Edge:バージョン111(2023年3月)以来フルサポート
  • Firefox:バージョン113(2023年5月)以来フルサポート
  • Safari:バージョン16.2(2022年12月)以来フルサポート

古いブラウザについては、レガシー構文で最初にグレースフルデグラデード。

/* フォールバック:sRGBグラデーション */
background: linear-gradient(to right, #FF5733, #3498DB);

/* モダン:OKLCH補間 */
@supports (background: linear-gradient(in oklch, red, blue)) {
  background: linear-gradient(in oklch to right, #FF5733, #3498DB);
}

重要なポイント

  • sRGB補間(CSSデフォルト)は、グラデーションがsRGBキューブの中央付近を通じて渡されるとき、淡く飽和度の低いミッドポイントを生成します。赤から緑と相補的な色のグラデーション内で特に見える。
  • HSL補間はいくつかのRGB問題を回避しますが、一貫性のない認知された明るさを導入します。そのライトネスチャネルは知覚的に均一ではありません。予期しない色相パスを生成できます。
  • OKLCH補間は、人間のビジョンの周りで設計されているため、活発で知覚的に一貫したミッドポイントを生成しています。グラデーションはその完全な範囲で飽和され、均等に明るく見えます。
  • あらゆるグラデーション内でin oklchを使用します。linear-gradient(in oklch to right, red, blue)。プログラムティック混合用color-mix(in oklch, color1 50%, color2)を使用します。
  • カラーコンバーターを使用して、16進またはRGB値をOKLCHに変換し、グラデーント設計に対する色補間の方法を理解します。
  • グラデーションジェネレーターでは、色スペースがグラデーント出力に影響を与える方法をプレビューできます。色のペアのもの。
  • 色相補間方向はshorter huelonger hueincreasing huedecreasing hueキーワードで制御できます。虹の効果と正確なマルチストップグラデーント制御に役立ちます。

関連カラー

関連ブランド

関連ツール