CSS カラーモジュール レベル 5

W3C 作業草案,

この文書の詳細情報
このバージョン:
https://www.w3.org/TR/2025/WD-css-color-5-20250318/
最新公開バージョン:
https://www.w3.org/TR/css-color-5/
編集者ドラフト:
https://drafts.csswg.org/css-color-5/
以前のバージョン:
履歴:
https://www.w3.org/standards/history/css-color-5/
フィードバック:
CSSWG 問題リポジトリ
編集者:
Chris Lilley (W3C)
Una Kravets (Google)
Lea Verou (招待された専門家)
Adam Argyle (Google)
この仕様の編集提案:
GitHub 編集者
デルタ仕様:
はい
テストスイート:
https://wpt.fyi/results/css/css-color/

概要

このモジュールは、CSS Color [css-color-4] を拡張し、色の変更関数、カスタムカラースペース(ICCプロファイル)、contrast-color()、light-dark()、およびdevice-cmyk()を追加します。

CSS は、構造化された文書(HTMLやXMLなど)の画面や紙などでのレンダリングを記述するための言語です。

この文書の状態

このセクションは、この文書が公開された時点での状態を説明します。 現在のW3Cの公開物のリストと、この技術報告書の最新の改訂版は、W3C技術報告書インデックス https://www.w3.org/TR/ で見つけることができます。

この文書は、CSS作業グループ によって 作業草案 として公開されました。 作業草案としての公開は、W3C およびそのメンバーによる承認を意味するものではありません。

この文書は草案であり、随時更新、置き換え、または他の文書によって廃止される可能性があります。 この文書を進行中の作業以外のものとして引用するのは不適切です。

フィードバックを送るには、GitHubでの問題の提出(推奨)を利用してください。タイトルに「css-color」という仕様コードを含めてください。例:「[css-color] …コメントの要約…」。 すべての問題とコメントはアーカイブされています。 または、www-style@w3.org という公開メーリングリスト(アーカイブ)にフィードバックを送ることもできます。

この文書は、2023年11月3日版のW3Cプロセス文書 に準拠しています。

この文書は、W3C特許ポリシー の下で運営されているグループによって作成されました。 W3Cは、グループの成果物に関連して行われた特許開示の公開リストを維持しています。 このページには、特許を開示するための指示も含まれています。 個人が、必須クレーム を含むと信じる特許について実際の知識を持っている場合、 W3C特許ポリシー第6節 に従って情報を開示する必要があります。

1. はじめに

このセクションは規範的ではありません。

このモジュールは、新しい関数 contrast-color()color-mix()、および light-dark() を追加し、既存のものを 相対色構文で拡張します。

また、color() 関数を拡張し、事前定義されたカラースペースだけでなく、ICCプロファイルで定義されたカスタムカラースペース(校正されたCMYKを含む)もCSSで使用できるようにします。

さらに、device-cmyk を追加し、校正されていないCMYK色を表現します。

2. <color> 構文

CSSの色は、<color> 型で表現されます:

<color> = <color-base> | currentColor | <system-color> | 
        <contrast-color()> | <device-cmyk()>  | <light-dark()>

<color-base> = <hex-color> | <color-function> | <named-color> | <color-mix()> | transparent
<color-function> = <rgb()> | <rgba()> |
            <hsl()> | <hsla()> | <hwb()> |
            <lab()> | <lch()> | <oklab()> | <oklch()> |
            <color()>

絶対色は、計算された値が絶対的な色彩測定解釈を持つ <color> です。 これは、次の値ではないことを意味します:

また、<color-mix()> または相対色構文内でこれらの値が使用されることもありません。

3. 色の混合: color-mix() 関数

ウェブ開発者、デザインツール、デザインシステムの開発者は、 コンポーネントの色の関係をスケーリングする際に色関数を使用することがよくあります。 複数のプラットフォームや複数のユーザー設定をサポートするデザインシステムの使用が増加している中で、 例えばUIのダークモードの機能が向上した場合など、 手動で色を設定する必要がなく、スキームを計算する単一のソースを持つことが さらに便利になります。

LCカラーピッカー
アメリカのクロロプレス地図

上図は、CIE LCH空間で動作するカラーピッカーです。 ここでは、2つの色を使用して 色スケールを定義しています (色相が一定のクロマ-明度平面上)。 下図は、クロロプレス地図で使用されている色スケールです。

現在、Sass、HSL値のcalc()、またはPostCSSがこれを行うために使用されています。 しかし、プリプロセッサは動的に調整された色で動作することができません。 現在のすべてのソリューションはsRGBガマットに制限されており、 HSLの知覚的な制限(色がカラーホイール上で密集している、 また、黄色と青のように視覚的に異なる明度を持つ2つの色が 同じHSL明度を持つ可能性がある)に制約されています。

このニーズを満たすために、color-mix()関数は2つの<color>仕様を取り、 指定された<color-space>で 指定された割合でそれらを混合した結果を返します。

color-mix() = color-mix( <color-interpolation-method> , [ <color> && <percentage [0,100]>? ]#{2})
テスト

3.1. パーセンテージの正規化

パーセンテージは0%から100%の範囲で指定する必要があります。負のパーセンテージは明確に禁止されています。パーセンテージの正規化は以下の通りです:

  1. p1 を最初のパーセンテージ、p2 を2番目のパーセンテージとします。

  2. 両方のパーセンテージが省略された場合、それぞれ50%(2色を均等に混ぜる)になります。

  3. そうでなければ、p2 が省略された場合は 100% - p1 となります。

  4. そうでなければ、p1 が省略された場合は 100% - p2 となります。

  5. そうでなければ、両方が指定されて合計が100%を超える場合、合計が100%になるようにスケーリングされます。

  6. そうでなければ、両方が指定されて合計が100%未満の場合、合計値がアルファ乗算率として保存されます。その後、合計が100%になるようにスケーリングされます。

つまり p1p1 / (p1 + p2) となり、p2p2 / (p1 + p2) となります。

テスト
これらの構文形式はすべて同等です:
color-mix(in lch, purple 50%, plum 50%)
color-mix(in lch, purple 50%, plum)
color-mix(in lch, purple, plum 50%)
color-mix(in lch, purple, plum)
color-mix(in lch, plum, purple)
color-mix(in lch, purple 80%, plum 80%)

すべて purple と plum の50-50ミックスを生成します。 lchでは: lch(51.51% 52.21 325.8) つまり rgb(68.51% 36.01% 68.29%) となります。

ただし、以下の形式はアルファ値が1未満となるため、同じではありません

color-mix(in lch, purple 30%, plum 30%)

これは lch(51.51% 52.21 325.8 / 0.6) つまり rgb(68.51% 36.01% 68.29% / 0.6) となります。

3.2. color-mixの結果の計算

両方のパーセンテージを正規化した後、結果は以下のアルゴリズムで生成されます:

  1. CSS Color 4 § 12. 色補間 で説明されているように、 両方の色は指定された補間<color-space>に変換されます。 この際、類似成分も考慮されます。

  2. 色は指定されたカラースペース内で補間されます。詳細は CSS Color 4 § 12. 色補間 を参照してください。 指定されたカラースペースが cylindrical-polar-color 空間の場合、 <hue-interpolation-method> により 色相の補間方法が制御されます。詳細は CSS Color 4 § 12.4 色相補間 を参照してください。 <hue-interpolation-method> が指定されていない場合は、 shorter が指定されたものとして扱います。

  3. パーセンテージの正規化でアルファ乗算率が生成されていた場合、補間結果のアルファ成分はこの乗算率で乗算されます。

テスト

ミックスの結果は、2番目の色から最初の色への進行の指定されたパーセンテージの位置にある色です。

注: 付随的に、パーセンテージ0%は他方の色を指定カラースペースへ変換したものを返し、100%は同じ色を指定カラースペースへ変換したものを返します。

この例は peru を40%、 palegoldenrod を60%混ぜます。
color-mix(in lch, peru 40%, palegoldenrod)

混色はlchカラースペースで行われます。 ここではニュートラルL軸を上から見下ろした図です:

2色の混色とその出力。 CIE L軸をab平面上から見下ろしています。 abの2つの軸があり、原点で交差し、グラフの中心にあります。

peruとpalegoldenrodのCIE LCHでの混色。 peruの色相角は正のa軸から63.677度、 palegoldenrodは98.834度です。 peruの彩度(中心軸からの距離)は54.011、 palegoldenrodは31.406です。 すべての混色は曲線上にあります。40%/60%の混合例を表示しています。

計算は以下の通りです:

この例はtealとoliveを混ぜています。 lchカラースペースで混色し、 各lch成分はtealの値の65%、oliveの値の35%で計算されています。

注: 色相と彩度で補間すると、 中間色も端点の色と同じくらい鮮やかになります。

color-mix(in lch, teal 65%, olive);

2色の混色とその出力。 CIE L軸をab平面上から見下ろしています。 abの2つの軸があり、原点で交差し、グラフの中心にあります。

tealとoliveの混色。 tealの色相角は正のa軸から196.4524度、 oliveは99.5746度です。 tealの彩度は31.6903、 oliveは56.8124です。 混色は破線の曲線上にあります。65%/35%の混合例を表示しています。

計算は以下の通りです:

3.3. color-mixにおける混色カラースペースの影響

混色に使用するカラースペースの選択は、結果に大きな影響を与えることがあります。

この例は、白と黒の50%ミックスを 3種類のカラースペースで示しています。
color-mix(in lch, white, black);
color-mix(in xyz, white, black);
color-mix(in srgb, white, black);

計算結果は以下の通りです:

LCHでの混色はL値が50%になり、 期待通りの完全な中間グレーとなります (Labで混色しても同じ結果になります。 LCHとLabのLightness軸は同じです)。

XYZでの混色は明るすぎる結果となります; XYZは線形光ですが知覚的均一性はありません。 sRGBでの混色はやや明るすぎます; sRGBは知覚的均一でも線形光でもありません。

この例は 赤と空色のミックスを xyzカラースペースで示しています。 ミックス比は赤が75.23%、青が24.77%です。
color-mix(in xyz, rgb(82.02% 30.21% 35.02%) 75.23%, rgb(5.64% 55.94% 85.31%));

計算結果は以下の通りです:

この例は、白と青の50%ミックスを 3種類のカラースペースで示しています。

color-mix(in lch, white, blue);
color-mix(in oklch, white, blue);
color-mix(in srgb, white, blue);

計算結果は以下の通りです:

この例は、2色を hslカラースペースで混色したものです。 混色する片方の色が sRGB ガマット外の値です。
color-mix(in hsl, color(display-p3 0 1 0) 80%, yellow);

計算結果は以下の通りです:

3.4. color-mixにおけるアルファ値の影響

これまでのcolor-mix()の例では すべて完全に不透明な色を使用していました。 例の簡易化のため、 プレ乗算および逆プレ乗算処理を 省略していました。 これは単に1で掛けて1で割るだけなので、結果は変わりません。

一般的な場合では、 色は非1のアルファ成分を持つことがあり、 プレ乗算、補間、逆プレ乗算の各ステップを 省略してはいけません。

この例は25%の半透明赤と 75%の半透明緑を sRGBで混色したものです。 正しい(プレ乗算済) および誤った(非プレ乗算) 計算例を示します。
color-mix(in srgb, rgb(100% 0% 0% / 0.7) 25%, rgb(0% 100% 0% / 0.2));

計算結果は以下の通りです:

誤った計算例:

これは大きな違いです。正しい結果と誤った結果のΔE2000は30.7!

パーセンテージ正規化でアルファ乗算率が生成された場合は、 計算の最後に追加のステップが加わります。

この例は前の例と似ていますが、 25%の半透明赤と 75%の半透明緑を sRGBで混色しています。

ただしこの場合はパーセンテージが 最初の色20%、2番目の色60%と指定されています。 合計は80%なので、アルファ乗算率は0.8です。

混色比率は100/80倍してスケーリングされます:
20% * 100/80 = 25%
60% * 100/80 = 75%
結果的に前の例と同じ混色比率になります。

color-mix(in srgb, rgb(100% 0% 0% / 0.7) 20%, rgb(0% 100% 0% / 0.2) 60%);

計算結果は以下の通りです:

注: 補間後のアルファにアルファ乗算率を掛けて それで逆プレ乗算してはいけません。 ミックス比率が100%にスケールされていない場合は正しいですが、 実際はスケール済みなので、この方法だと混色色が二重に調整されてしまいます。

4. 相対色

4.1. 相対色の処理モデル

この仕様の前のレベルでは、 色関数は全ての色成分を直接指定することでしか 色を絶対的に指定できませんでした。

新しい 相対色 構文は 現代的な色構文を拡張し、 既存の色を色関数で修飾できるようにします。 基準色 が 指定されている場合、 各色成分(およびアルファ成分が指定されていればアルファ成分)は 直接指定することも、 基準色から取得することもできます (必要なら数式関数で修飾可能)。

基準色と相対色は同じ色関数を使う必要はありません。

全ての操作は 相対色関数のカラースペース内で行われます; 基準色元の指定カラースペースが異なる色関数だった場合、 まず選択された色関数へ変換され、 各成分に意味のある値が割り当てられます成分キーワードは 相対色のカラースペースを参照します。基準色のカラースペースではありません。

相対色のアルファ値が省略された場合、 基準色のアルファ値をデフォルトとします (絶対構文の場合の100%ではありません)。

相対色構文を使用する場合、色成分の値は 直接指定された場合も 色空間変換によって得られた場合も 基準範囲にクランプされずそのまま保持されます。 これにより、出力色空間が表現可能ならガマット外の値も保存されます。

ただし、相対色構文ではアルファ成分の値は 直接指定された場合も 色空間変換によって得られた場合も基準範囲にクランプされます

欠損成分は CSS Color 4 § 12.2 欠損成分の補間 と同様に処理されます: 基準カラースペースと相対関数のカラースペース双方で 類似成分を確認し 欠損として引き継ぎます。

多くの場合、相対色構文では 成分キーワードを 対応する引数で使用しますが、 どの位置でも使用できます。

成分を通常の位置以外で使う場合は注意してください。 パーセンテージが数値に変換される際、 その数値が他の位置で使われても 位置の違いによる「自動スケーリング」はありません。

4.2. 相対色構文

各関数で相対色に対応するための 構文の詳細は以下に記載しますが、 全て共通の構造に従います:

成分キーワード<number> または none を返します。 元が <percentage><angle> で指定されていた場合、その<percentage><number>に変換され、 <angle>は度数の <number>正規単位)として[0, 360]範囲に解決されます。

テスト
例えば、色が<percentage>で指定されている場合、 同じカラースペースでRCSを使うと解決された<number>の形になります:
html { --bluegreen:  oklab(54.3% -22.5% -5%); }
.overlay {
  background:  oklab(from var(--bluegreen) calc(1.0 - l) calc(a * 0.8) b);
}

この例では、指定されたパーセンテージは数値に解決され、 oklab(0.543 -0.09 -0.02) になります。 RCSの結果色は l = 1 - 0.543 = 0.457、 a = -0.09 * 0.8 = -0.072、 bはそのまま -0.02: oklab(0.457 -0.072 -0.02) となります。

例えば、基準色の色相成分が度単位の<angle>で指定されている場合、 同じカラースペースでRCSを使うと解決された<number>の形になります:
html { --base:  oklch(52.6% 0.115 44.6deg) }
.summary {
  background:  oklch(from var(--base) l c  calc(h + 90));
}

この例ではRCSの結果色は oklch(0.526 0.115 134.6) となります。

もし基準色の色相<angle>が ラジアンやターンなど他の単位で指定されていても、 解決された<number>は度数になります。

成分キーワード数式関数で使うことで、 基準色をより高度に操作できます。
html { --color: green; }
.foo {
  --darker-accent: lch(from var(--color) calc(l / 2) c h);
}

この例では、基準色の明度を半分にして 色を暗くしています。他の成分は変化しません。

また、基準色は色キーワード (つまりsRGB)ですが、 lch()関数で使われることで 自動的にLCH色として解釈されます。

例えばテーマ色が不透明に指定されていても、 特定の場面で半透明にしたい場合:
html { --bg-color:  blue; }
.overlay {
  background:  rgb(from var(--bg-color) r g b / 80%);
}

この例では、基準色のr, g, b成分はそのままで キーワードで指定して値を基準色から取得していますが、 不透明度は80%に指定して少し透明にしています。 基準色の不透明度が何であっても関係ありません。

例えば、sRGBのガマット外のDisplay P3色も クリップされずに表現できます。
--vivid-yellow:  color(display-p3 1 1 0); 
--paler-yellow:  color(from var(--vivid-yellow) srgb r g calc(b + 0.5));

ここで --vivid-yellow をsRGBに変換すると rgb(100% 100% -34.63%) となり 負の青成分もクランプされません。 RCS計算結果は rgb(100% 100% 15.37%) となります。

例えば基準色のアルファが0.7で、それを2倍しようとすると 結果のアルファは1になり、1.4にはなりません。
--tan:  oklch(78% 0.06 75 / 0.7);
--deeper-tan:  oklch(from var(--tan) l c h / calc(alpha * 2));
例えば、色をグレースケール化する大まかな近似:
--blue-into-gray: rgb(from var(--color)
                    calc(r * .3 + g * .59 + b * .11)
                    calc(r * .3 + g * .59 + b * .11)
                    calc(r * .3 + g * .59 + b * .11));

この方法を使うと、redrgb(76.5 76.5 76.5)limergb(150.45 150.45 150.45)bluergb(150.45 150.45 150.45)になります。 より中間色のdarkolivegreen (RGB値 rgb(85 107 47))は rgb(93.8 93.8 93.8) となります。

(粗い理由:まず、見た目は輝度計算のようですが 実際は赤・緑・青値が線形光でなくガンマ空間で処理されています。 また、重み係数はsRGBではなく 古いNTSC色空間のものです。)

(この例は構文の説明目的です。 色をグレースケール化する簡単かつ正確な方法は oklch()関数を使うことです。 この色空間は人間の知覚に近く、 oklch(from var(--color) l 0 h) とすれば 明度は維持され、彩度は0になり 色味がなくなります。)

例えば、

color: color(from color(srgb 0 0 0 / 60%) srgb alpha 0.6 0.6 / 0.9);

アルファ成分は<number>に解決され、0.6になります。結果の色は color(srgb 0.6 0.6 0.6 / 0.9) となります。

しかし次の例でもアルファは0.6ですが、 rgb()構文の色成分範囲0〜255のため 結果色が大きく異なります:

color: rgb(from rgb(0 0 0 / 60%) alpha 153 153 / 0.9);

結果は rgb(0.6 153 153 / 0.9) となり、153 153 153 / 0.9 にはなりません。

この例では無彩色の基準色が 色相を欠損していて、 相対色も 色相を欠損しており、 その色を使うグラデーションに影響します。
html { --bg:  hsl(none 3% 50%); }
.foo {
  --darker-bg:  oklch(from var(--bg) calc(l * 0.8) c h);
}
.bar {
  background: linear-gradient(in Oklab to right,   var(--darker-bg),   #4C3);
}

--bg を OKLCh に変換すると oklch(0.592 0.009 17.42) ですが 類似色の色相成分は引き継がれて oklch(0.592 0.009 none) となります。 この値を相対関数で使うことで 暗い色 oklch(0.474 0.009 none) が得られます。

グラデーションの明るい緑は oklch(0.743 0.222 141.6) で、 補間されるともう一方の色もその色相を持ち oklch(0.474 0.009 141.6) になります。

よってグラデーションは一定の緑色系の色相になります。

実装がこの引き継ぎを行わなかった場合、 灰色の --darker-bg は色相0となり、 グラデーションの始端が赤みを帯びてしまいます。

正しい(上)と誤った(下・赤寄り)グラデーション。

ただし、欠損値に対して計算を行う場合、none は 0として扱われます。

4.3. 相対sRGB色

現代的な色構文rgb()およびrgba()関数の文法は以下のように拡張されます:

<modern-rgb-syntax> = rgb( [ from <color> ]?
        [ <number> | <percentage> | none]{3}
        [ / [<alpha-value> | none] ]?  )
<modern-rgba-syntax> = rgba( [ from <color> ]?
        [ <number> | <percentage> | none]{3}
        [ / [<alpha-value> | none] ]?  )

相対色構文のrgb()またはrgba()関数の中で、許可される成分キーワードは以下の通りです:

テスト
sRGB色空間の色成分を操作する例:
rgb(from  indianred 255 g b)

これは indianred のsRGB値 (205 92 92) を取り、 赤成分を255に置き換えて rgb(255 92 92) を生成します。

相対sRGB色構文はレガシーでないRGB構文形式にのみ適用されます。

例えば、カンマ区切りのrgbaレガシー色構文を使おうとした場合は誤りです
rgba(from  darkblue 16, 32, b, 0.5 )
正しくは次のように記述します:
rgb(from  darkblue 16 32 b / 0.5 )

これは darkblue のsRGB値 (0 0 139) を取り、 赤・緑・アルファ成分を置き換えて rgb(16 32 139 / 0.5) を生成します。

4.4. 相対HSL色

現代的な色構文hsl()およびhsla()関数の文法は以下のように拡張されます:

<modern-hsl-syntax> = hsl([from <color>]?
          [<hue> | none]
          [<percentage> | <number> | none]
          [<percentage> | <number> | none]
          [ / [<alpha-value> | none] ]? )
<modern-hsla-syntax> = hsla([from <color>]?
        [<hue> | none]
        [<percentage> | <number> | none]
        [<percentage> | <number> | none]
        [ / [<alpha-value> | none] ]? )

相対色構文のhsl()またはhsla()関数の中で、許可される成分キーワードは以下の通りです:

テスト
この例では色相角に180度加え、補色を作ります。
--accent:  lightseagreen;
--complement:   hsl(from var(--accent) calc(h + 180) s l);

lightseagreen は hsl(177deg 70% 41%) なので --complement は hsl(357deg 70% 41%) となります。

相対HSL色構文はレガシーでないHSL構文形式にのみ適用されます。

4.5. 相対HWB色

hwb()関数の文法は以下のように拡張されます:

hwb() = hwb([from <color>]?
        [<hue> | none]
        [<percentage> | <number> | none]
        [<percentage> | <number> | none]
        [ / [<alpha-value> | none] ]? )

相対色構文のhwb()関数の中で、許可される成分キーワードは以下の通りです:

テスト

4.6. 相対Lab色

lab()関数の文法は以下のように拡張されます:

lab() = lab([from <color>]?
        [<percentage> | <number> | none]
        [<percentage> | <number> | none]
        [<percentage> | <number> | none]
        [ / [<alpha-value> | none] ]? )

相対色構文のlab()関数の中で、許可される成分キーワードは以下の通りです:

ベース色の透明度を調整する複数の方法:

全ての調整はロスレスで、ガマットクリッピングが発生しません。lab()は可視色全体をカバーしているためです。 sRGBベース関数('rgb()', 'hsl()', 'hwb()'など)のアルファ調整では 計算の過程でsRGBへ変換されるため 必要なステップとしてHSLやHWBの計算時にアルファ値調整に加えsRGB変換も行われます。

色を完全にグレースケール化し、明度はそのまま保持する例:
--mycolor:  orchid;
// orchidは lab(62.753 52.460 -34.103)
--mygray:  lab(from var(--mycolor) l 0 0)
// mygrayは lab(62.753 0 0) で、これは rgb(59.515% 59.515% 59.515%)

4.7. 相対Oklab色

oklab()関数の文法は以下のように拡張されます:

oklab() = oklab([from <color>]?
          [<percentage> | <number> | none]
          [<percentage> | <number> | none]
          [<percentage> | <number> | none]
          [ / [<alpha-value> | none] ]? )

相対色構文のoklab()関数の中で、許可される成分キーワードは以下の通りです:

4.8. 相対LCH色

lch()関数の文法は以下のように拡張されます:

lch() = lch([from <color>]?
        [<percentage> | <number> | none]
        [<percentage> | <number> | none]
        [<hue> | none]
        [ / [<alpha-value> | none] ]? )

相対色構文のlch()関数の中で、許可される成分キーワードは以下の通りです:

テスト
lch(from peru calc(l * 0.8) c h) peru(lch(62.2532% 54.0114 63.6769))より20%暗い色を生成します。彩度と色相は変化しません。 結果は lch(49.80256 54.0114 63.6769)
この例では色相角に180度加えて補色を作ります。
--accent:  lightseagreen;
--complement:   lch(from var(--accent) l c calc(h + 180));

lightseagreen は lch(65.4937 39.4484 190.1013) なので --complement は lch(65.4937 39.4484 370.1013)

色を完全にグレースケール化し、明度はそのまま保持する例:
--mycolor:  orchid;
// orchidは lch(62.753 62.571 326.973)
--mygray:  lch(from var(--mycolor) l 0 h)
// mygrayは lch(62.753 0 326.973) で、これは rgb(59.515% 59.515% 59.515%)

ただしこの場合(色相を保持したため)、再び彩度を戻すこともできます:

--mymuted:  lch(from var(--mygray) l 30 h);
// mymutedは lch(62.753 30 326.973) で、これは rgb(72.710% 53.293% 71.224%)

ただし、HSLと違い、操作結果が常にガマット内になるとは限りません。

この例では、明度と彩度は同じで 120度異なる三分配色(トライアド)を作ろうとしています。 基準色はRGBガマット内ですが、 LCHで色相を回転すると ガマット外の色になります。
--mycolor:  lch(60% 90 320);
lch(from var(--mycolor) l c calc(h - 120));

この場合、非常に高彩度な青緑色 lch(60% 90 200) となり、color(srgb -0.6 0.698 0.772) なのでsRGBではガマット外(赤成分が負)。 実際、display-p3でも color(display-p3 -0.46 0.68 0.758) rec2020でも color(rec2020 -0.14 0.623 0.729) でガマット外となります。

sRGBガマット内の最も近い色は lch(60.71% 37.56 201.1) であり、 rgb(0% 64.2% 66.3%) ですが 彩度(37.5)が90から大幅に減少します。

CIE CH平面の図。相対色操作を示します。 a軸とb軸がラベル付けされ、中央で交差しています。 中央の明度軸を上から見下ろしています。 sRGB色空間の最大ガマットは 不規則な凸多角形として表示されます。

この図はCIE ab平面上のsRGBガマットを示しています。 小さい円は原色・副原色を示します。 基準色は大きい円で、sRGBガマット内です。 しかしLCH色相を-120°回転すると ガマット外(灰色塗り+赤枠)になります。 ガマットマッピング後の結果は彩度が大幅に低下します。

同じ操作をHSLで行えばガマット内の結果になりますが、 他の点で満足できません:

--mycolor:  lch(60% 90 320);
hsl(from var(--mycolor) calc(h - 120) s l);

HSLでは --mycolor は hsl(289.18 93.136% 65.531%) なので、120度引くと hsl(169.18 93.136% 65.531%) になります。 この結果をLCHに戻すと lch(89.0345% 49.3503 178.714) となり、HSLで色相を回転すると 明度は60%から89%に跳ね上がり、 彩度も90から49に減り、 色相も実際には120度ではなく141度変化しています。

4.9. 相対OKLCh色

oklch()関数の文法は以下のように拡張されます:

oklch() = oklch([from <color>]?
          [<percentage> | <number> | none]
          [<percentage> | <number> | none]
          [<hue> | none]
          [ / [<alpha-value> | none] ]? )

相対色構文のoklch()関数の中で、許可される成分キーワードは以下の通りです:

テスト

OKLChは知覚的均一で彩度保持性も高く、 軸が色の分かりやすい属性に対応しているため、 色操作にはOKLChが適しています。

この例では、明度と彩度は同じで 120度異なる三分配色(トライアド)を作ろうとしています。 今回はOKLChで操作します。 基準色はRGBガマット内ですが、 OKLChで色相を回転すると やはりガマット外の色になります。
--mycolor:  lch(60% 90 320);
oklch(from var(--mycolor) l c calc(h - 120));

--mycolorは oklch(0.69012 0.25077 319.893)。 色相から120を引くと、非常に高彩度な青緑色 oklch(0.69012 0.25077 199.893) となり、sRGBガマット外です。 color(srgb -0.6018 0.7621 0.8448) で赤成分が負です。 OKLCh彩度を減らしてガマット内にすると、 oklch(0.69012 0.1173 199.893)になります。 OKLChの彩度は0.251から0.117に減少しています。

5. 事前定義およびカスタム色空間の指定:color()関数

color() 関数は、特定の色空間(他の多くの色関数が暗黙的にsRGB色空間で動作するのに対し、明示的に指定された色空間)で 色を指定できます。

このレベルでは、color()関数が拡張され、 CSS Color 4 §  10. 事前定義色空間で定義されているプリセット空間に加えて カスタム色空間も指定できるようになります。

また、絶対色だけでなく相対色も指定できるよう拡張されています。

構文は以下の通りです:

color() = color( [from <color>]? <colorspace-params> [ / [ <alpha-value> | none ] ]? )
<colorspace-params> = [<custom-params> | <predefined-rgb-params> | <xyz-params>]
<custom-params> = <dashed-ident> [ <number> | <percentage> | none ]+
<predefined-rgb-params> = <predefined-rgb> [ <number> | <percentage> | none ]{3}
<predefined-rgb> = srgb | srgb-linear | display-p3 | a98-rgb | prophoto-rgb | rec2020
<xyz-params> = <xyz> [ <number> | <percentage> | none ]{3}
<xyz> = xyz | xyz-d50 | xyz-d65

color関数は明示的に指定された色空間で色を指定するためのパラメータを受け取ります。

この関数は、下記で説明する無効な色 または有効な色を表します。

無効な色でない場合はすべて有効な色です。

有効な色であっても、出力デバイス(スクリーン、プロジェクタ、プリンタ)で 再現可能な色域の範囲外である場合があります。 その場合は、その色空間に対してガマット外と言います。

ガマット外の色は成分値が0や0%未満、1や100%超過となります。 これらは無効ではなく、表示のためにガマットマッピングによって 相対色表色意図で0/0%〜1/100%の範囲に収められ、 計算値時に処理されます。

有効な色は出力デバイス(スクリーン、プリンタなど)のガマット内か ガマット外のいずれかです。

5.1. 相対 color() 関数色

相対色構文のcolor()関数で<custom-params>を使う場合、 許可される成分キーワードの数と名前は:

相対色構文のcolor()関数で<predefined-rgb-params>を使う場合、 許可される成分キーワードは:

相対色構文のcolor()関数で<xyz-params>を使う場合、 許可される成分キーワードは:

相対色構文のcolor()関数で <predefined-rgb-params>または<xyz-params> のいずれかを使う場合、追加で許可される成分キーワードは:

パラメータの形式は以下の通りです:

テスト
例:CIE XYZ D65 色空間で相対色構文を使い、 ベース色と同じ色度で輝度のみ半分にした色を生成:
--base:  color(display-p3 0.7 0.5 0.1);
--dark:  color(from var(--base) xyz-d65 calc(x/2) calc(y/2) calc(z/2));

基準色は color(xyz-d65 0.281 0.253 0.044) 相対色は color(xyz-d65 0.14 0.126 0.022) です。

5.2. カスタム色空間

CSSではを色プロファイル参照で指定できます。 例えばキャリブレーション済みCMYKプリンタ、 RGB色空間、 または特性評価済みの任意のカラー・モノクロ出力デバイスなどです。

この例では4つのキャリブレーション済み色を指定しています: 2つはカスタム空間 (SWOPコートCMYK印刷機用と広色域7色インクプリンタ用)、 残り2つは事前定義空間 (ProPhoto RGB と display-p3 RGB)。 すべて数値パラメータは0.0〜1.0の範囲(例えば0〜255ではなく)です。
color: color(--swopc 0.0134 0.8078 0.7451 0.3019);
color: color(--indigo 0.0941 0.6274 0.3372 0.1647 0 0.0706 0.1216);
color: color(prophoto-rgb 0.9137 0.5882 0.4784);
color: color(display-p3 0.3804 0.9921 0.1412);

事前定義色空間CSS Color 4 §  10. 事前定義色空間を使わない色は <dashed-ident>を使うことで区別され、 スタイルシート内のどこかで一致する@color-profile規則が必要です。 これにより名前とプロファイルデータが関連付けられます。

テスト
@color-profile --swopc {
  src: url('http://example.org/swop-coated.icc');}
@color-profile --indigo {
  src: url('http://example.org/indigo-seven.icc');}

5.3. 色プロファイルの指定:@color-profile at規則

@color-profile規則は 色プロファイルを定義・命名し、 後でcolor()関数で色指定に利用できます。

定義は以下の通りです:

@color-profile = @color-profile [<dashed-ident> | device-cmyk] { <declaration-list> }
テスト

<dashed-ident>色プロファイルの名前を指定し、 CSSスタイルシートで利用されます。 また、device-cmykキーワードを使うと、 この色プロファイルが有効なら device-cmyk指定色の解決に用いられます。

@color-profile規則はこの仕様で定義されたディスクリプタを受け付けます。

名前: src
対象: @color-profile
値: <url>
初期値: n/a

srcディスクリプタは 色プロファイル情報取得用のURLを指定します。

取得したICCプロファイルが有効となる条件:

プロファイルが無効なら、このプロファイルを参照する全CSS色は 無効な色となります。

外部色プロファイルの取得は、@color-profile規則ruleを受け取り、スタイルリソースの取得ruleのURLで行い、 スタイルシートはrule親CSSスタイルシート、 destinationは "color-profile"、CORSモードは "cors"、 processResponseはレスポンス|/res|とnull・失敗・ バイトストリームbyteStreamに対して: byteStreamがバイトストリームなら それをパースした色プロファイルを適用します。

注: ICCプロファイルのInternet Media Type(MIMEタイプ)は application/vnd.iccprofileです。

名前: rendering-intent
対象: @color-profile
値: relative-colorimetric | absolute-colorimetric | perceptual | saturation
初期値: relative-colorimetric

色プロファイルは 「レンダリングインテント」(rendering intents)を持ち、 より小さいガマットへの色のガマットマッピング方法を定義します。 多くの場合プロファイルはインテントを1つのみ持ちますが、複数ある場合は rendering-intentディスクリプタで選択します。

レンダリングインテントは4種類あります [ICC]:

relative-colorimetric
メディア相対色域マッピング(media-relative colorimetric)は、出力媒体ガマット内のソース色を 媒体の白点に対して変更せずに保持することを要求します。出力媒体ガマット外のソース色は、 様々な方法でガマット境界上の色にマッピングされます。

メディア相対色域レンダリングインテントは ブラックポイント補正(black point compensation)と併用されることが多く、 ソース媒体の黒点も出力媒体の黒点にマッピングします。 この方法ではソースの白点を出力の白点にマッピングしなければなりません。 ブラックポイント補正が使われる場合はソース黒点も出力黒点にマッピングされます。 白点変更へ適応するアルゴリズムも使うべきです。 ガマット内の色の相対関係は保持しますが、 ガマット外の色の相対関係は変化することがあります。

absolute-colorimetric
ICC絶対色域マッピング(ICC-absolute colorimetric)は、 出力媒体ガマット内のソース色を採用白(perfect reflecting diffuser)に対して変更せずに保持します。 ガマット外の色はガマット境界にマッピングされます。この方法はガマット内の色のマッチ精度が最も高いですが、 出力媒体白点がソースより低いとハイライトクリッピングが発生します。 そのため、厳密な色マッチが必要かつハイライトクリッピングが問題にならない用途でのみ推奨されます。

この方法では白点・黒点のマッチングを無効化しなければなりません。一般的にテスト以外では推奨されません。

perceptual
この方法は画像用途でよく使われます。ソース画像と出力媒体間で大きな違いがある場合(例:スクリーン画像を印刷物に再現) ソース画像の色を出力媒体向けに再最適化します。プロプライエタリな方法で ソース・出力ガマット両方内の色が変更されることもありますが、 芸術的意図は再現されるべきです。ソース画像の誤り補正は行いません。

注: v2 ICCプロファイルでは 知覚的参照媒体が規定されておらず、 相互運用性の問題が生じることがあります。 v2 ICCプロファイルを使う場合は知覚的インテントよりも ブラックポイント補正付きメディア相対色域インテントが安全です。 特定のプロファイル組み合わせで望む結果になるか確認が必要です。

この方法はターゲットデバイスガマットへのマッピング時に ピクセル間の相対色値を保持します。 ガマット内のピクセル値も変更される場合があり、 色相シフトや不連続・全体的外観の維持のためです。

saturation
このオプションは元の相対彩度(chroma)を維持し、 ソリッドカラーを純粋に保つために作られました。 ただし知覚的インテント同様に相互運用性の問題があり、 v4プロファイルでも解決されません。特定のプロファイル組み合わせで期待通りになる場合のみ推奨です。 このオプションは元のピクセルの相対彩度値を維持するべきです。 ガマット外の色は同じ彩度でガマット内に収めます。
名前: components
対象: @color-profile
値: <ident>#
初期値: n/a

色プロファイルは色空間の成分数を自由に定義できます。 例えばCMYKプロファイルは4成分 cyan, magenta, yellow, black 4成分の加法型スクリーンプロファイルなら r, g, y, b なども可能です。

このディスクリプタ値は<ident> トークンのカンマ区切りリストです。 各<ident>は成分名で、 色プロファイルで使われる順序で並び、 トークン数が成分数を決めます。

このディスクリプタは4成分を cyan, magenta, yellow, black と宣言します:
components: cyan, magenta, yellow, black

より短い名前にする場合:

components: c,m,y,k
このディスクリプタは7成分 cyan, magenta, yellow, black, orange, green, violet と宣言します:
components: cyan, magenta, yellow, black, orange, green, violet

成分がASCII大文字小文字無視noneに一致する場合は、 ディスクリプタは無効です。欠損値用トークンと衝突するためです。

成分名がCSS Values 4 § 10.7.1 数値定数: e, piで定義されたCSS数値定数と衝突しても、成分自体は有効ですが calc()内では 数値定数が優先され予期しない結果になります。

このディスクリプタは成分名にpiを使ってしまい、 相対色構文で予期しない結果になります。
@color-profile --unwise {
  src: url(https://example.com/unwise);
  components: mi, pi, ni;
}
--base: color(--unwise 35% 20% 8%);
--accent: color(from var(--base) mi calc(pi * 2) calc(ni / 2));

この例では --accent の成分値は 35%、 3.14159265358979 * 2 = 6.28318530717959、 4% です。

5.4. CSSと印刷:キャリブレーションCMYKやその他の印刷用色空間の利用

@color-profile at規則はRGB色空間だけに限定されません。 画面は通常RGB色を直接表示しますが、 プリンタは多くの場合CMYKで色を表現します。

シアン・マゼンタ・イエロー・ブラック(CMYK)による4色印刷や、 シアン・マゼンタ・イエロー・ブラック・オレンジ・グリーン・バイオレット(CMYKOGV)など 高忠実度広色域印刷もCSSで行えます。 その場合、使用するインク・用紙・トータルインクカバレッジ・機器に対応する ICCプロファイルが必要です。

例:ISO 12647-2:2004 / Amd 1:2007オフセット印刷 FOGRA39特性データ、 115gsmコート紙、 インクリミット300% Total Area Coverage時 [FOGRA39]
@color-profile --fogra39 {
  src: url('https://example.org/Coated_Fogra39L_VIGC_300.icc');
}
.header {
  background-color:   color(--fogra39 0% 70% 20% 0%);
  }

ここでcolor()関数はまずプロファイル名を指定し、 次にシアン・マゼンタ・イエロー・ブラックの割合(パーセント値)を与えています。

このプロファイルでは、結果色は lab(63.673303% 51.576902 5.811058) であり、 rgb(93.124, 44.098% 57.491%) となります。

CMYKの組み合わせから実際の色が分かるので、 印刷結果のオンスクリーン可視化(ソフトプルーフ)が可能です。

また、色が分かっていれば (アンチエイリアスや合成、グラデーション利用なども) 通常通り処理できます。

色付き四角のグリッド。列はA~F、行は1~4でラベル付け。

カラーチェッカー。印刷・写真業界で色忠実度確認に使われます。 各パッチのLab値平均測定値をsRGBに変換した矩形。 ほとんど見えない円はLab値をFOGRA51 [FOGRA51] ICCプロファイルでCMYKへ変換し、逆変換したLab値をsRGBに変換して表示しています。

円が最も見えるパッチ(3行目1列目)は、 FOGRA51 CMYK空間のガマット外だったためです。

下表は各パッチごとにCMYK往復後のLab値と元Lab値のDeltaE 2000を示します。DeltaE 2000が1以上で肉眼で判別可能です。

A B C D E F
1 0.06 0.07 0.03 0.04 0.06 0.17
2 0.03 0.75 0.05 0.06 0.03 0.02
3 1.9 0.04 0.06 0.05 0.02 0.05
4 0.03 0.08 0.03 0.03 0.04 0.80
例:ISO 12647-2:2004オフセット印刷 CGATS/SWOP TR005 2007特性データ グレード5用紙 インクリミット300% Total Area Coverage 中程度グレー成分置換(GCR)。
@color-profile --swop5c {
  src: url('https://example.org/SWOP2006_Coated5v2.icc');
}
.header {
  background-color:   color(--swop5c 0% 70% 20% 0%);
}

このプロファイルでは、同じCMYK割合(前例と同じ)で 結果色は lab(64.965217% 52.119710 5.406966) rgb(94.903% 45.248% 59.104%) となります。

CMYK色がsRGBガマット外の場合、 メディアクエリなどでフォールバック色を指定できます。

この例は先ほどのFOGRA39設定で、 sRGBガマット外の明るい緑を指定しています。 display-p3ガマット内なので、 広色域画面や印刷ではそのまま表示され、 sRGB画面ではより控えめなフォールバック色が使われます。
@media (color-gamut: srgb) {
  .header {
    background-color:   rgb(8.154% 60.9704% 37.184%);
    }
}
@media print, (color-gamut: p3){
  .header {
    background-color:   color(--fogra39 90% 0% 90% 0%);
    }
}

このCMYK色はlab(56.596645% -58.995875 28.072154) または lch(56.596645% 65.33421077211648 154.5533771086801)。 sRGBではrgb(-60.568% 62.558% 32.390%)となり、 赤成分が大きく負なのでガマット外です。

彩度を下げてガマット内にすると lch(56.596645% 51 154.5533771086801) rgb(8.154% 60.9704% 37.184%)となり、 これが手動で指定したフォールバック色です。

広色域画面ではdisplay-p3ガマット内(display-p3(0.1658 0.6147 0.3533))です。

色は4色(CMYK)だけに限定されません。例えば広色域7色インクセットも利用できます。

この例はCMYKOGV7色印刷用のFOGRA55ベータデータセット [FOGRA55] を使用しています。 黒・シアン・マゼンタ・イエローの4インクはFOGRA51と同じで同じ結果です。 残りの3インクは:

測定条件はM1(用紙蛍光剤を考慮し、分光光度計にUVカットなし)。

@color-profile --fogra55beta {
  src: url('https://example.org/2020_13.003_FOGRA55beta_CL_Profile.icc');
}
.dark_skin {
  background-color: 
  color(--fogra55beta 0.183596 0.464444 0.461729 0.612490 0.156903 0.000000 0.000000);
}
.light_skin {
  background-color: 
  color(--fogra55beta 0.070804 0.334971 0.321802 0.215606 0.103107 0.000000 0.000000);
}
.blue_sky {
  background-color: 
  color(--fogra55beta 0.572088 0.229346 0.081708 0.282044 0.000000 0.000000 0.168260);
}
.foliage {
  background-color: 
  color(--fogra55beta 0.314566 0.145687 0.661941 0.582879 0.000000 0.234362 0.000000);
}
.blue_flower {
  background-color: 
  color(--fogra55beta 0.375515 0.259934 0.034849 0.107161 0.000000 0.000000 0.308200);
}
.bluish_green {
  background-color: 
  color(--fogra55beta 0.397575 0.010047 0.223682 0.031140 0.000000 0.317066 0.000000);
}

5.5. CMYK色からLabへの変換

キャリブレーション済みCMYK色空間からLabへの変換は、 通常ICCプロファイルでLab値を参照することで行われます。

5.6. Lab色からCMYKへの変換

印刷では、 Lab色をプリンタの色空間に変換する必要があります。

これも通常、ICCプロファイルでCMYK値を参照することで行います。

6. 非キャリブレーションCMYK色:device-cmyk()関数

プリンタがキャリブレーションされていない場合でも、 特定インク組み合わせの出力が実験や印刷サンプル帳で分かっている場合は、 デバイス依存の方法でCMYK色を表現するのが便利です。

注: 実際の色結果が不明なため、 CSS処理系は近似を試みる場合があります。 この近似は実際の印刷結果と大きく異なる可能性があります。

device-cmyk()関数はこのような色指定を可能にします:

device-cmyk() = <legacy-device-cmyk-syntax> | <modern-device-cmyk-syntax>
<legacy-device-cmyk-syntax> = device-cmyk( <number>#{4} )
<modern-device-cmyk-syntax> = device-cmyk( <cmyk-component>{4} [ / [ <alpha-value> | none ] ]? )
<cmyk-component> = <number> | <percentage> | none

device-cmyk()関数の引数は順にシアン・マゼンタ・イエロー・ブラック成分を指定します。 0〜1の数値または現代構文では0%〜100%のパーセンテージです。 どちらも等価で線形に変換されます。 0や0%未満、1や100%超過の値も無効ではなく、 計算値時に0/0%または1/100%にクランプされます。

現代構文では第5引数がアルファ成分を指定します。 rgb()関数の第4引数と同じ扱いです。 省略時は100%になります。

歴史的理由で、device-cmyk()レガシー色構文もサポートしています。

通常、印刷系アプリケーションは色をCMYKで保持し、 そのままプリンタに送ります。 しかしこうした色には色域的な解釈がなく、 グラデーション・合成・ブレンド等には使えません。

そのため、Device CMYK色は等価な色に変換する必要があります。 これはHSLやHWBからRGBへの変換のように単純ではなく、 出力デバイスの特性によって変換方法が異なります。

  1. ユーザー・作者・UAスタイルシートに @color-profileのdevice-cmyk定義があり、 srcディスクリプタのリソースが取得可能で、 有効なCMYK ICCプロファイルであり、 UAがICCプロファイルを処理できる場合は、 device-cmyk()関数の計算値はCMYK色のLab値になる。
  2. それ以外の場合は、 device-cmyk()関数の計算値は CMYK色を次の単純変換アルゴリズムでsRGBに変換した値になる。
例:@color-profile無しの場合、 次の色は単純変換で等価です。
color:  device-cmyk(0 81% 81% 30%);
color:  rgb(178 34 34);
color:  firebrick;
指定スタイルシートで@color-profileが指定されている場合、 次の色は色域変換で等価です。
color:  device-cmyk(0 81% 81% 30%);
color:  lab(45.060% 45.477 35.459)
color:  rgb(70.690% 26.851% 19.724%);

単純変換は近似的であり、 インクの色域、ドットゲイン、RGB空間の色域などの知識がないためです。

色付き四角のグリッド。列はA~F、行は1~4でラベル付け。

カラーチェッカー。印刷・写真業界で色忠実度確認に使われます。 各パッチのLab値平均測定値をsRGBに変換した矩形。 円はLab値をICCプロファイルでCMYKに変換し、単純変換でsRGBに戻したものを示します。

下表は各パッチごとにCMYK往復後のLab値と元Lab値のDeltaE 2000を示します。DeltaE 2000が1以上で肉眼で判別可能、5以上だと全く違う色になります。

A B C D E F
1 11.33 9.36 5.66 7.52 12.39 21.58
2 6.40 8.79 11.77 17.16 11.91 3.97
3 12.1 17.00 3.38 1.94 18.08 14.97
4 1.89 6.56 7.85 8.76 9.82 10.29

6.1. 非キャリブレーションCMYKとsRGB系色の単純変換

CMYKからRGBAへ単純変換するには:

RGBAからCMYKへ単純変換するには:

7. 使用中のcolor-schemeへの反応:light-dark()関数

システム色は現在のcolor-scheme値に応じて反応できます。 light-dark()関数は 著者にも同様の機能を提供します。

light-dark() = light-dark( <color>, <color> )

この関数は、使用中のcolor schemelightまたは不明の場合は 最初の色の計算値に、 使用中のcolor schemedarkの場合は 2番目の色の計算値になります。

テスト

8. 動的に十分なコントラストを持つテキスト色を指定する:contrast-color()関数

色を動的に生成する場合、背景色に十分なコントラストを持つテキスト色を指定するのは難しいことがあります。 contrast-color()関数は、 指定色を背景色としてテキスト色に使ったときに 十分なコントラストが保証される色を自動的に提供します。

注: 可読性は複雑な課題であり、十分なコントラストはその一要素に過ぎません。 コントラストのある色の組み合わせがあっても、フォント・文字サイズ・周囲の色などさまざまな要因で テキストの可読性が保証されるわけではありません。

contrast-color() = contrast-color( <color> )

contrast-color()は、または のどちらか、入力色を背景にした時に最大コントラストとなる方を返します。 が同じコントラストの場合は になります。

どちらの色を返すかのコントラスト判定アルゴリズムは 現行標準ではUA定義です。

注: 将来の仕様では コントラスト判定アルゴリズムや用途、返される色の制御が強化される予定です。

UAは単純にWCAG 2.1 section 1.4.3 Contrast (Minimum)の判定アルゴリズムだけで 明色・暗色の選択をしないことが推奨されます。既知の問題が複数あるためです。 ただしこの関数の返す色はWCAG 2.1 section 1.4.3 Contrast (Minimum) のAA大型テキスト基準は満たすべきです。法令上これが必要な場合があるためです。

9. 色の補間

9.1. 補間用の色空間

<color-interpolation-method>カスタム色空間の利用も可能になりました:

<color-space> = <rectangular-color-space> | <polar-color-space> | <custom-color-space>
<rectangular-color-space> = srgb | srgb-linear | display-p3 | a98-rgb | prophoto-rgb | rec2020 | lab | oklab | xyz | xyz-d50 | xyz-d65
<polar-color-space> = hsl | hwb | lch | oklch
<custom-color-space> = <dashed-ident>
<hue-interpolation-method> = [ shorter | longer | increasing | decreasing ] hue
<color-interpolation-method> = in [ <rectangular-color-space> | <polar-color-space> <hue-interpolation-method>? | <custom-color-space> ]

<dashed-ident>は 有効な@color-profile規則で宣言されていなければならず、 そうでない場合は<color-interpolation-method>は無効です。

10. <color>値の解決

10.1. color-mix()値の解決

すべての<color>パラメータが それぞれの色空間で色に解決される場合、 計算値は指定された混合色空間で混合された色となり、 CSS Color 4 §  14. Resolving <color> Valuesに従い解決されます。 そうでない場合(関数内でcurrentColorを使用した場合)は、 各<color>パラメータについて CSS Color 4 §  14. Resolving <color> Valuesで解決し、 子要素への継承を維持したままcolor-mix()関数の計算値となります。

テスト

10.2. 相対色構文値の解決

すべての<color>パラメータが それぞれの色空間で色に解決される場合、 計算値は指定されたRCS色空間での絶対<color>値となり、 CSS Color 4 §  14. Resolving <color> Valuesで解決されます。

テスト

そうでない場合(関数内でcurrentColorを使用した場合)は、 計算値は相対色構文関数となり、 基準<color>パラメータをCSS Color 4 §  14. Resolving <color> Valuesで解決したものとして、 子要素への継承を維持したままになります。

テスト

10.3. device-cmyk値の解決

計算値・使用値は 指定されたデバイス固有CMYK色 (成分は<number><percentage>ではない) と指定されたアルファ成分 (<number><percentage>ではない、未指定なら不透明)です。

使用値は操作によって異なり、 CMYK対応デバイスへの描画時はCMYK色としてレンダリングされる場合があります。 非CMYK色との合成や非CMYKデバイスへの描画時は、 § 6 非キャリブレーションCMYK色:device-cmyk()関数に従い変換されます。

例:
 device-cmyk(0% 70% 20% 0%)

指定値・実際の値は

 device-cmyk(0 0.7 0.2 0)

ICCプロファイルを理解し適切なプロファイルがインストールされている実装なら、使用値は

 lab(63.673% 51.577 5.811)

注: すべての色と同様、使用値はスクリプトから取得できません。

11. シリアライズ

このセクションはCSS Color 4 §  15. シリアライズ <color> 値を拡張し、 color-mix()device-cmyk()、 および 相対色関数の結果のシリアライズについて追加します。

このセクションでは、仕様で使われる文字列と対応する文字は次のとおりです。

文字列 文字
" " U+0020 スペース
"," U+002C コンマ
"-" U+002D ハイフン
"." U+002E ピリオド
"/" U+002F スラッシュ

文字列"."は、ロケールに関係なく 10進区切り文字として使われ、千単位区切りは使いません。

通常通り、 結果のアルファ値がちょうど1なら シリアライズ時に省略します。 暗黙の1(完全不透明)がデフォルトです。

11.1. color-mix()のシリアライズ

color-mix()関数の宣言値のシリアライズは 文字列"color-mix(in "から始まり、 指定された<color-space>をすべて小文字で、 続いて", "、 1つ目の指定色、 スペース、 1つ目のパーセンテージ(下記)、 ", "、 2つ目の指定色、 2つ目のパーセンテージ(下記)、 ")"となります。

color-mix()関数宣言値の1つ目のパーセンテージのシリアライズ:

color-mix()関数宣言値の2つ目のパーセンテージのシリアライズ:

注: calc()値は 未知扱いなので決して50%と等しくならず、 他と合計で100%になることもありません。

例:次の宣言値のシリアライズは
color-mix(in oklab, teal, peru 40%)

→ 文字列 "color-mix(in oklab, teal 60%, peru)"

次の宣言値のシリアライズは

color-mix(in oklab, teal 50%, peru 50%)

→ 文字列 "color-mix(in oklab, teal, peru)"

次の宣言値のシリアライズは

color-mix(in oklab, teal 70%, peru 70%)

→ 文字列 "color-mix(in oklab, teal 70%, peru 70%)" これは正規化後に50%ずつになる事実はパーセンテージ正規化後に判明するためです。

color-mix()関数結果のシリアライズは mix内でcurrentColorキーワードが使われているかで異なります。 使われている場合は宣言値としてシリアライズされます。 これにより、colorプロパティ値が異なる子要素でも正しい混色が使えます。 そうでない場合は <color>として CSS Color 4 §  15. シリアライズ <color> 値に従いシリアライズされます。 使用される形式は"in"で指定した色空間によります:

混色色空間 形式
srgb color(srgb r g b)
srgb-linear color(srgb-linear r g b)
display-p3 color(display-p3 r g b)
a98-rgb color(a98-rgb r g b)
prophoto-rgb color(prophoto-rgb r g b)
rec2020 color(rec2020 r g b)
hsl color(srgb r g b)
hwb color(srgb r g b)
xyz-d65 color(xyz-d65 x y z)
xyz-d50 color(xyz-d50 x y z)
xyz color(xyz-d65 x y z) ¹
lab lab(l a b)
lch lch(l c h)
oklab oklab(l a b)
oklch oklch(l c h)
¹
xyzxyz-d65のエイリアスだからです
テスト

往復時の最小精度はCSS Color 4 §  15. シリアライズ <color> 値で規定されたものと同じです。

この混色結果
color-mix(in lch, peru 40%, palegoldenrod)

は文字列 "lch(79.7256 40.448 84.771)" でシリアライズされます、 一方、

color-mix(in srgb, peru 40%, palegoldenrod)

は文字列 "color(srgb 0.8816 0.7545 0.4988)" でシリアライズされます。

11.2. 元色のシリアライズ

他の色関数内で元色として使われる色の宣言値のシリアライズは:

  1. rgb()rgba()hsl()hsla()の場合:

注: 現代構文かレガシー構文かにかかわらず同じシリアライズ。

  1. hwb()lab()lch()oklab()oklch()の場合:

  1. color()の場合:

11.3. 相対色関数のシリアライズ

相対色の宣言値のシリアライズは:

  1. rgb()rgba()hsl()hsla()の場合:

  1. hwb()lab()lch()oklab()oklch()の場合:

  1. color()の場合:

例:宣言値のシリアライズ
OkLcH(from peru  l    c  h)

→ 文字列 "oklch(from peru l c h)"

例:宣言値のシリアライズ
rgb(from red calc(r / 2) g calc(30%));

→ 文字列 "rgb(from red calc(0.5 * r) g calc(30%))" 計算値のシリアライズは "color(srgb 0.5 0 0.3)"

例:宣言値のシリアライズ
hsl(from hsl(none 10% 50%) h s l);

→ 文字列 "hsl(from hsl(none 10% 50%) h s l)" 計算値のシリアライズは "color(srgb 0.55 0.45 0.45)"

例:宣言値のシリアライズ
hsl(from hsl(127.9 302% 25.33%) h s l);

→ 文字列 "hsl(from hsl(127.9 302% 25.33%) h s l)" 計算値のシリアライズは "color(srgb -0.511666 1.018266 -0.310225)"

下記HTML(この要素のcolorプロパティに注目):
<div id="example" 
  style="background-color: rgb(from currentcolor r g calc(b / 2)); 
  color: blue;">
</div>

background-colorの宣言値のシリアライズは "rgb(from currentcolor r g calc(b / 2))" 計算値のシリアライズは "color(srgb 0 0 0.5)"

相対色関数結果のシリアライズは、 currentColor元色かどうかで異なります。 そうなら宣言値としてシリアライズされるので、 colorプロパティ値が異なる子要素でも正しい値が使われます。 そうでなければ、 解決値(<color>で、 CSS Color 4 §  15. シリアライズ <color> 値に従う)になります。

使用される形式は 相対色の色空間によります:

混色色空間 形式
srgb color(srgb r g b)
srgb-linear color(srgb-linear r g b)
display-p3 color(display-p3 r g b)
a98-rgb color(a98-rgb r g b)
prophoto-rgb color(prophoto-rgb r g b)
rec2020 color(rec2020 r g b)
hsl color(srgb r g b)
hwb color(srgb r g b)
xyz-d65 color(xyz-d65 x y z)
xyz-d50 color(xyz-d50 x y z)
xyz color(xyz-d65 x y z)
lab lab(l a b)
lch lch(l c h)
oklab oklab(l a b)
oklch oklch(l c h)
テスト

往復時の最小精度はCSS Color 4 § 15.5 color()関数値のシリアライズで規定されたものと同じです。

シリアライズ結果
lch(from peru calc(l * 0.8) calc(c * 0.7) calc(h + 180)) 

→ 文字列 "lch(49.80224 37.80819 243.6803)"

11.4. カスタム色空間のシリアライズ

color()成分値の保持精度、 つまりシリアライズ値の有効数字の桁数は本仕様では定義されませんが、 CMYK色空間の場合は少なくとも 8ビット精度で値を往復できるだけの精度が必要です。 これは少なくとも小数点以下2桁を要しますが、 末尾のゼロが省略されている場合もあります。

下記色のシリアライズ値:

@color-profile --swop5c {src: url('https://example.org/SWOP2006_Coated5v2.icc');
}
.header {
background-color:    color(--swop5c  0% 70.0% 20.00% .0%);
}

→ 文字列 "color(--swop5c 0 0.7 0.2 0)"

11.5. device-cmyk値のシリアライズ

device-cmyk()値のシリアライズ形式は、 計算値から導出され、 関数名は小文字でdevice-cmyk()形式です。

成分値は10進数でシリアライズされ、 <number>として扱います。 成分値間の区切りには ASCIIスペース " " を1つ使用します。

成分値の末尾の小数部分のゼロは省略し、 小数部分が全てゼロなら小数点も省略します。

下記色のシリアライズ値:

  device-cmyk(0 81% 81% 30%)

→ 文字列 "device-cmyk(0 0.81 0.81 0.3)"

device-cmyk()成分値の保持精度、 つまりシリアライズ値の有効数字の桁数は本仕様では定義されませんが、 少なくとも8ビット精度で値を往復できるだけの精度が必要です。 これは少なくとも小数点以下2桁を要しますが、 末尾のゼロが省略されている場合もあります。 値は+∞方向に丸め、切り捨てしません。

アルファ値が1(単位)の場合は明示的にシリアライズしません。 非単位アルファ値は明示的にシリアライズし、 " / "(ASCIIスペース、スラッシュ、スペース)の文字列で 黒("k")成分値とアルファ値を区切ります。

12. API

12.1. CSSColorProfileRuleインターフェイス

CSSColorProfileRuleインターフェイスは@color-profile 規則を表します。

[Exposed=Window]
interface CSSColorProfileRule : CSSRule {
  readonly attribute CSSOMString name ;
  readonly attribute CSSOMString src ;
  readonly attribute CSSOMString renderingIntent ;
  readonly attribute CSSOMString components ;
};
name, CSSOMString, readonly
name属性の取得時は その規則に定義された色プロファイルnameの シリアライズを含むCSSOMStringオブジェクトを返します。
src, CSSOMString, readonly
renderingIntent, CSSOMString, readonly
components, CSSOMString, readonly
残りの属性の取得時は その規則に定義されたディスクリプタのシリアライズを含むCSSOMStringオブジェクトを返します。 規則でそのディスクリプタが指定されていなければ 属性は空文字列を返します。

13. デフォルトスタイル規則

以下のスタイルシートは参考例であり、規範的なものではありません。このスタイルシートは、実装がHTMLファミリー文書のデフォルトスタイリングの一部として利用可能です。

/* 従来型デスクトップユーザーエージェントのリンク色 */
:link { color: LinkText; }
:visited { color: VisitedText; }
:active { color: ActiveText; }

/* device-cmykに対する妥当で保守的なデフォルト */
@color-profile device-cmyk {
  src: url('https://drafts.csswg.org/css-color-4/ICCprofiles/Coated_Fogra39L_VIGC_300.icc');
}

14. セキュリティに関する考慮事項

この仕様はCSSにオンデマンドのICCプロファイルダウンロード機能を追加します。 これらには実行可能コードは含まれておらず、 セキュリティリスクの増加にはなりません。

15. プライバシーに関する考慮事項

この仕様に関して新たなプライバシー懸念は報告されていません。

16. アクセシビリティに関する考慮事項

この仕様は、ユーザー指定色(動的色を含む)を背景にしたテキストの十分なコントラストを確保する方法を追加します。

17. 変更点

17.1. 2024年2月29日 作業草案以降の変更

17.2. 2022年6月28日 作業草案以降の変更

17.3. 2022年4月28日 作業草案以降の変更

17.4. 2021年12月15日 作業草案以降の変更

17.5. 2021年6月1日 作業草案以降の変更

17.6. 2020年6月10日FPWD以降の変更

17.7. CSS Color 4からの変更点

CSS Color 4と比較して大きな変更点として、 CSSの色がsRGBやdisplay-p3など既定のRGB空間に限定されなくなりました。

これに対応するため、いくつか新機能が追加されています:

  1. color() 関数が@color-profile at規則で拡張され、プロファイル化されたデバイス依存色(キャリブレーションCMYK含む)を扱えるようになりました。
  2. device-cmyk()関数で、出力デバイス固有のCMYK色空間で非キャリブレーション色を指定可能になりました。

さらに新しいcolor-mix()関数で、 指定した色空間で2色を混色し新しい色を得ることができます。

適合性

文書上の慣例

適合性要件は、記述的断定とRFC 2119用語の組み合わせで表現されます。規範部分における “MUST”、 “MUST NOT”、 “REQUIRED”、 “SHALL”、 “SHALL NOT”、 “SHOULD”、 “SHOULD NOT”、 “RECOMMENDED”、 “MAY”、 “OPTIONAL” というキーワードは、RFC 2119に記載されている通りに解釈されます。 ただし、本仕様書の可読性のため、これらのキーワードはすべて大文字では記載されていません。

本仕様の文章は、明示的に非規範的と記載されたセクション、例、注釈を除き、すべて規範的です。 [RFC2119]

本仕様の例は、「例えば」などの語で導入されるか、class="example"で規範文から区別されて提示されます。

これは情報提供のための例です。

情報的な注は「注」で始まり、class="note"で規範文から区別されて提示されます。

注: これは情報提供のための注です。

助言は注意喚起のための規範セクションであり、<strong class="advisement">で他の規範文と区別され、次のように表示されます: UAはアクセシビリティ代替手段を提供しなければならない。

テスト

本仕様の内容に関するテストは、このような「テスト」ブロックで文書化されている場合があります。 このようなブロックは非規範的です。


適合性クラス

本仕様への適合性は、3つの適合性クラスについて定義されています:

スタイルシート
CSS スタイルシート
レンダラー
スタイルシートの意味を解釈し、それを利用する文書をレンダリングするUA
オーサリングツール
スタイルシートを作成するUA

スタイルシートは、本モジュールで定義された構文を用いるすべての文が、汎用CSS文法および本モジュールで定義された各機能の個別文法に従い有効であれば、本仕様に適合します。

レンダラーは、スタイルシートを適切な仕様に従い解釈することに加え、本仕様で定義されたすべての機能を正しくパースし文書をレンダリングすることで、本仕様に適合します。ただし、デバイスの制約によりUAが文書を正しくレンダリングできない場合でも、UAが非適合となるわけではありません。(例: UAはモノクロモニター上で色をレンダリングする必要はありません。)

オーサリングツールは、汎用CSS文法および本モジュールの各機能の個別文法に従い構文的に正しいスタイルシートを書き、本モジュールで記載されたスタイルシートのその他すべての適合性要件を満たしていれば、本仕様に適合します。

部分実装

作者が将来互換性のあるパース規則を利用してフォールバック値を指定できるように、CSSレンダラーは、利用可能なレベルのサポートがないat規則、プロパティ、プロパティ値、キーワード、その他の構文要素を無効として扱わなければならず適切に無視しなければなりません。特に、ユーザーエージェントはサポートされていない成分値のみを選択的に無視し、同じ複数値プロパティ宣言内のサポートされている値のみを適用してはならず、無効値(サポートされていない値)は宣言全体を無視しなければなりません。

不安定機能・独自拡張の実装

将来の安定CSS機能との衝突を避けるため、CSSWGはベストプラクティスに従って、不安定機能および独自拡張を実装することを推奨します。

非実験的実装

仕様が現行標準の候補勧告段階に達した後は、非実験的な実装が可能となり、実装者は仕様通りに正しく実装されていることを証明できるCRレベルの機能について、プレフィックスなしでリリースすべきです。

CSSの相互運用性を確立・維持するため、CSSワーキンググループは非実験的CSSレンダラーに対し、CSS機能のプレフィックスなし実装をリリースする前に実装レポート(必要に応じてそのテストケース)をW3Cへ提出することを求めています。W3Cに提出されたテストケースはCSSワーキンググループによるレビュー・修正の対象となります。

テストケース・実装レポートの提出方法についてはCSSワーキンググループWebサイト https://www.w3.org/Style/CSS/Test/ を参照してください。 質問は public-css-testsuite@w3.org メーリングリストへ。

索引

本仕様で定義されている用語

参照によって定義される用語

参考文献

規範的参考文献

[CSS-CASCADE-5]
Elika Etemad・Miriam Suzanne・Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2022年1月13日. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-COLOR-4]
Chris Lilley・Tab Atkins Jr.・Lea Verou. CSS Color Module Level 4. 2024年2月13日. CRD. URL: https://www.w3.org/TR/css-color-4/
[CSS-COLOR-ADJUST-1]
Elika Etemad・他. CSS Color Adjustment Module Level 1. 2022年6月14日. CRD. URL: https://www.w3.org/TR/css-color-adjust-1/
[CSS-SYNTAX-3]
Tab Atkins Jr.・Simon Sapin. CSS Syntax Module Level 3. 2021年12月24日. CRD. URL: https://www.w3.org/TR/css-syntax-3/
[CSS-VALUES-4]
Tab Atkins Jr.・Elika Etemad. CSS Values and Units Module Level 4. 2024年3月12日. WD. URL: https://www.w3.org/TR/css-values-4/
[CSSOM-1]
Daniel Glazman・Emilio Cobos Álvarez. CSS Object Model (CSSOM). 2021年8月26日. WD. URL: https://www.w3.org/TR/cssom-1/
[FETCH]
Anne van Kesteren. Fetch Standard. 現行標準. URL: https://fetch.spec.whatwg.org/
[ICC]
ICC.1:2022 (Profile version 4.4.0.0). 2022年5月. URL: http://www.color.org/specification/ICC.1-2022-05.pdf
[INFRA]
Anne van Kesteren・Domenic Denicola. Infra Standard. 現行標準. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[WEBIDL]
Edgar Chen・Timothy Gu. Web IDL Standard. 現行標準. URL: https://webidl.spec.whatwg.org/

参考情報

[FOGRA39]
ISO 12647-2:2004 / Amd 1, オフセット商業・特殊印刷 ISO 12647-2準拠、紙種1または2(グロスまたはマットコートオフセット、115 g/m²)、スクリーン周波数60/cm. 2006年. URL: https://www.color.org/chardata/FOGRA39.xalter
[FOGRA51]
ISO 12647-2:2013, 網点カラー分解・校正・本印刷の工程管理(Part 2: オフセット平版印刷、PS 1、プレミアムコート、115 g/m²、中程度の蛍光性基材). 2015年. URL: https://www.color.org/chardata/fogra51.xalter
[FOGRA55]
CMYKOGVベースのガマット交換空間. 2021年. URL: https://fogra.org/en/research/prepress-technology/multiprimary-printing-13003

プロパティ索引

定義されたプロパティはありません。

@color-profile ディスクリプタ一覧

名前 初期値
components <ident># n/a
rendering-intent relative-colorimetric | absolute-colorimetric | perceptual | saturation relative-colorimetric
src <url> n/a

IDL索引

[Exposed=Window]
interface CSSColorProfileRule : CSSRule {
  readonly attribute CSSOMString name ;
  readonly attribute CSSOMString src ;
  readonly attribute CSSOMString renderingIntent ;
  readonly attribute CSSOMString components ;
};