CSS color-mix()

CSS の color-mix() 関数を使用すると、サポートされている色空間の色を CSS から直接混合できます。

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 16.2.

Source

color-mix() 以前は、色を暗くしたり、明るくしたり、彩度を下げたりするために、デベロッパーは CSS プリプロセッサまたはカラー チャンネルの calc() を使用していました。

SCSS を使用した以前のコード
.color-mixing-with-sass {
  /* Sass: equally mix red with white */
  --red-white-mix: color.mix(red, white);
}

Sass は、カラー CSS 仕様の最先端を維持する上で素晴らしい働きをしています。しかし、CSS で色を混ぜる方法はありませんでした。近づけるには、部分的な色の値の計算を行う必要があります。CSS で今日のミキシングをシミュレートする方法の例を次に示します。

HSL を使用する前
.color-mixing-with-vanilla-css-before {
  --lightness: 50%;
  --red: hsl(0 50% var(--lightness));

  /* add "white" to red
     by adding 25% to the lightness channel
  */
  --lightred: hsl(0 50% calc(var(--lightness) + 25%);
}

color-mix() を使用すると、CSS に色を混在させることができます。デベロッパーは、どの色空間で混合するか、混合する各色の優位性をどの程度にするかを選択できます。

変更後
.color-mixing-after {
  /* equally mix red with white */
  --red-white-mix: color-mix(in oklab, red, white);

  /* equally mix red with white in srgb */
  --red-white-mix-srgb: color-mix(in srgb, red, white);
}

これらを兼ね備えた人材を、Google は求めています。柔軟性、パワー、フル機能の API。Love it.

CSS で色を混合する

CSS は複数の色空間と色域の世界に存在するため、ミキシングの色空間を指定することは必須です。さらに、色空間が異なると、ブレンドの結果が大きく変わる可能性があるため、色空間の効果を把握しておくと、必要な結果を得ることができます。

インタラクティブな紹介については、こちらの color-mix() ツールをお試しください。 - 各色空間の効果を確認します。 - 円柱色空間(lch、oklch、hsl、hwb)で混合する場合の色相補間の効果を確認します。 - 上部の 2 つのカラーボックスのいずれかをクリックして、混合する色を変更します。- スライダーを使用してミキシング比率を変更します。- 生成された color-mix() CSS コードは下部にあります。

さまざまな色空間でのミキシング

混合(およびグラデーション)のデフォルトの色空間は oklab です。一貫した結果が得られます。ニーズに合わせてミックスを調整するために、代替の色空間を指定することもできます。

たとえば、black と white の場合、混合する色空間はそれほど大きな違いはないですよね?これは間違いです。

color-mix(in srgb, black, white);
color-mix(in srgb-linear, black, white);
color-mix(in lch, black, white);
color-mix(in oklch, black, white);
color-mix(in lab, black, white);
color-mix(in oklab, black, white);
color-mix(in xyz, black, white);
7 つの色空間(srgb、linear-srgb、lch、oklch、lab、oklab、xyz)それぞれで、黒と白を混ぜた結果が表示されます。約 5 種類の異なる色合いが表示され、各色空間がグレーに混ざる場合でも異なることがわかります。
デモを試す

大きな効果があります。

別の例として、blue と white を見てみましょう。これを選択したのは、色空間の形状が結果に影響する可能性があるためです。この場合、ほとんどの色空間は白から青に移動する際に紫になります。また、oklab がミキシングに非常に信頼性の高い色空間であることも示しています。これは、白と青を混ぜたときにほとんどの人が期待する色(紫ではない)に最も近いからです。

color-mix(in srgb, blue, white);
color-mix(in srgb-linear, blue, white);
color-mix(in lch, blue, white);
color-mix(in oklch, blue, white);
color-mix(in lab, blue, white);
color-mix(in oklab, blue, white);
color-mix(in xyz, blue, white);
7 つの色空間(srgb、linear-srgb、lch、oklch、lab、oklab、xyz)がそれぞれ異なる結果を示している。多くはピンクや紫で、実際に青いものはほとんどありません。
デモを試す

color-mix() で色空間の効果を学ぶことは、グラデーションの作成にも役立ちます。Color 4 構文では、グラデーションで色空間を指定することもできます。グラデーションは、空間の領域にわたる混合を示します。

.black-to-white-gradient-in-each-space {
  --srgb: linear-gradient(to right in srgb, black, white);
  --srgb-linear: linear-gradient(to right in srgb-linear, black, white);
  --lab: linear-gradient(to right in lab, black, white);
  --oklab: linear-gradient(to right in oklab, black, white);
  --lch: linear-gradient(to right in lch, black, white);
  --oklch: linear-gradient(to right in oklch, black, white);
  --hsl: linear-gradient(to right in hsl, black, white);
  --hwb: linear-gradient(to right in hwb, black, white);
  --xyz: linear-gradient(to right in xyz, black, white);
  --xyz-d50: linear-gradient(to right in xyz-d50, black, white);
  --xzy-d65: linear-gradient(to right in xyz-d65, black, white);
}
さまざまな色空間の黒から白へのグラデーション。
デモを試す

「最適な」色空間があるかどうか疑問に思われるかもしれませんが、そのようなものはありません。そのため、非常に多くのオプションがあります。また、1 つの「最適な」色空間があれば、新しい色空間が考案されることもありません(oklch と oklab を参照)。それぞれの色空間には、輝きを放ち、適切な選択となる独自の瞬間があります。

たとえば、鮮やかなミックス結果が必要な場合は、hsl または hwb を使用します。次のデモでは、2 つの鮮やかな色(マゼンタとライム)が混ざり合っています。hsl と hwb はどちらも鮮やかな結果を生成しますが、srgb と oklab は彩度の低い色を生成します。

前の段落で説明したミックスの結果。
デモを試す

一貫性と繊細さを求める場合は、oklab を使用します。次のデモでは、青と黒を混合しています。hsl と hwb では、過度に鮮やかで色相がシフトした色が生成されますが、srgb と oklab では、より暗い青が生成されます。

前の段落で説明したミックスの結果。
デモを試す

color-mix() プレイグラウンドで 5 分ほどかけて、さまざまな色や空間をテストしてみると、各空間の利点がわかってきます。また、ユーザー インターフェースにおける色空間の可能性を調整するにあたり、色空間に関するガイダンスも増えることが予想されます。

色相の補間方法を調整する

円筒形の色空間を混合するように選択した場合(角度を受け入れる h 色相チャンネルを持つ色空間)、補間が shorter、longer、decreasing、increasing のいずれになるかを指定できます。詳しくは、こちらの HD カラーガイドをご覧ください。

同じ青と白の混合の例ですが、今回は、異なる色相補間方法を使用する円柱空間のみです。

前の段落で説明したミックスの結果。
デモを試す

色相補間を可視化するために作成した別の Codepen を紹介します。これは特にグラデーション用です。このツールは、色相補間が指定されたときに各色空間がどのように混合結果を生成するかを理解するのに役立ちます。ぜひお試しください。

さまざまな色構文を混合する

これまでは、blue や white などの CSS の名前付きの色を主に組み合わせてきました。CSS カラー ミキシングは、2 つの異なる色空間の色を混合する準備ができています。2 つの色が同じ空間にない場合に共通の空間を設定するため、ミキシングの色空間を指定することが重要になります。

color-mix(in oklch, hsl(200deg 50% 50%), color(display-p3 .5 0 .5));

前の例では、hsl と display-p3 が oklch に変換されてから、ミックスされます。かなりクールで柔軟性があります。

混合比の調整

これまでの例のほとんどで示してきたように、混ぜ合わせるたびに各色を等量にしたいということはあまりないでしょう。幸いなことに、結果として得られるミックスで各色をどの程度表示するかを指定する構文があります。

このトピックを始めるにあたり、同等のミックスの例を以下に示します(仕様に基づく)。

.ratios-syntax-examples {
  /* omit the percentage for equal mixes */
  color: color-mix(in lch, purple, plum);
  color: color-mix(in lch, plum, purple);

  /* percentage can go on either side of the color */
  color: color-mix(in lch, purple 50%, plum 50%);
  color: color-mix(in lch, 50% purple, 50% plum);

  /* percentage on just one color? other color gets the remainder */
  color: color-mix(in lch, purple 50%, plum);
  color: color-mix(in lch, purple, plum 50%);

  /* percentages > 100% are equally clamped */
  color: color-mix(in lch, purple 80%, plum 80%);
  /* above mix is clamped to this */
  color: color-mix(in lch, purple 50%, plum 50%);
}

これらの例は、エッジケースをよく説明していると思います。最初の例では、50% は必須ではありませんが、必要に応じて指定できることを示しています。最後の例は、比率を合計すると 100% を超える興味深いケースを示しています。この場合、合計が 100% になるように均等にクランプされます。

また、1 つの色のみに比率を指定した場合、もう 1 つの色は 100% の残りの比率と見なされます。この動作を説明する例をいくつか示します。

color-mix(in lch, purple 40%, plum) /* plum assigned 60% */
color-mix(in lch, purple, 60% plum) /* purple assigned 40% */
color-mix(in lch, purple 40%, plum 60%) /* no auto assignments */

これらの例は、次の 2 つのルールを示しています。 1. 比率が 100% を超えると、クランプされて均等に分配されます。1. 1 つの比率のみが指定されている場合、もう一方の色は 100 からその比率を引いた値に設定されます。

最後のルールは少しわかりにくいかもしれません。両方の色にパーセンテージが指定されていて、合計が 100% にならない場合はどうなるでしょうか。

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

この color-mix() の組み合わせにより、透明性、40% の透明性が実現します。比率の合計が 100% にならない場合、結果のミックスは不透明になります。どちらの色も完全に混ざることはありません。

ネスト color-mix()

すべての CSS と同様に、ネストは適切に処理され、想定どおりに動作します。内部関数が最初に解決され、その値が親コンテキストに返されます。

color-mix(in lch, purple 40%, color-mix(plum, white))

必要な結果を得るために、必要なだけネストしてください。

ライトとダークのカラーパターンを構築する

color-mix() でカラーパターンを作成しましょう。

基本的なカラーパターン

次の CSS では、ブランドの 16 進数色コードに基づいてライトモードとダークモードが作成されます。ライトモードでは、2 つの濃い青色のテキスト色と、非常に明るい白色の背景サーフェス色が作成されます。次に、ダークモードのメディアクエリで、カスタム プロパティに新しい色が割り当てられ、背景が暗く、テキストの色が明るくなります。

:root {
  /* a base brand color */
  --brand: #0af;

  /* very dark brand blue */
  --text1: color-mix(in oklab, var(--brand) 25%, black);
  --text2: color-mix(in oklab, var(--brand) 40%, black);

  /* very bright brand white */
  --surface1: color-mix(in oklab, var(--brand) 5%, white);
}

@media (prefers-color-scheme: dark) {
  :root {
    --text1: color-mix(in oklab, var(--brand) 15%, white);
    --text2: color-mix(in oklab, var(--brand) 40%, white);
    --surface1: color-mix(in oklab, var(--brand) 5%, black);
  }
}

これらはすべて、ブランドカラーに白または黒を混ぜることで実現できます。

中間カラーパターン

ライトモードとダークモード以外のテーマを追加することで、さらに一歩進めることができます。次のデモでは、ラジオボタン グループを変更すると、HTML タグ [color-scheme="auto"] の属性が更新され、セレクタが条件付きでカラーテーマを適用できるようになります。

この中間デモでは、すべてのテーマカラーが :root にリストされているカラー テーマ設定手法も示しています。これにより、すべての設定をまとめて確認し、必要に応じて調整できます。スタイルシートの後半では、定義した変数を使用できます。これにより、色の操作がすべて最初の :root ブロックに含まれるため、スタイルシートで色の操作を探す必要がなくなります。

その他の興味深いユースケース

Ana Tudor 氏が、いくつかのユースケースを学習するための優れたデモを公開しています。

DevTools で color-mix() をデバッグする

Chrome DevTools は color-mix() を強力にサポートしています。構文を認識してハイライト表示し、[スタイル] ペインのスタイルのすぐ横にミックスのプレビューを作成して、代替色を選択できるようにします。

DevTools では次のように表示されます。

Chrome DevTools で color-mix 構文を検査している様子。

ミキシングをお楽しみください。