color-mix()

Baseline 2023
新推出

自 ⁨2023 年 5 月⁩起,此功能可在最新的设备和浏览器版本上使用。此功能可能无法在旧版设备或浏览器上使用。

color-mix() 函数式表示法接收两个 <color> 值,并返回按给定数量在给定色彩空间中混合它们的结果。

语法

css
/* Polar color space */
color-mix(in hsl, hsl(200 50 80), coral)
color-mix(in hsl, hsl(200 50 80) 20%, coral 80%)

/* Rectangular color space */
color-mix(in srgb, plum, #123456)
color-mix(in lab, plum 60%, #123456 50%)

/* With hue interpolation method */
color-mix(in lch increasing hue, hsl(200deg 50% 80%), coral)
color-mix(in lch longer hue, hsl(200deg 50% 80%) 44%, coral 16%)

参数

color-mix( <color-interpolation-method>, <color> [<percentage>], <color> [<percentage>] ) 接受以下参数:

<color-interpolation-method>

指定混合颜色时应使用的插值方法。它由 in 关键字和一个色彩空间形式化语法中列出的色彩空间之一)组成,并且可以选择性地包含一个 <hue-interpolation-method>

<color>

要混合的颜色;可以是任何有效的 <color> 值。

<percentage> 可选

一个百分比值,指定要混合的相应颜色的量;可以是 0%100%(含)之间的任何 <percentage> 值。

返回值

一个 <color>;在给定的 <color-space> 中,按指定的量和色相方向混合颜色的结果。

描述

color-mix() 函数可以在给定的色彩空间中,使用更短或更长的色相插值方法,将任意类型的两个 <color> 值按特定比例混合。浏览器支持多种色彩空间;color-mix() 函数可以混合多种颜色,不局限于 sRGB 色彩空间。

这个演示允许你选择两种颜色,color-onecolor-two,然后将它们混合,还可以选择性地设置每种颜色的百分比、混合颜色的色彩空间以及插值方法。源颜色显示在外部,混合后的颜色显示在中间。你可以通过点击颜色,然后使用弹出的颜色选择器来更改颜色。使用滑块更改每种颜色的百分比值。通过下拉菜单更改色彩空间。

选择色彩空间

选择正确的色彩空间对于产生预期的结果很重要。对于相同的待混合颜色,不同的色彩空间可能更适合不同的插值用例。

  • 如果希望得到物理上混合两种色光的结果,那么 CIE XYZ 或 srgb-linear 色彩空间是合适的,因为它们在光强度上是线性的。
  • 如果颜色需要感知上均匀分布(例如在渐变中),那么 Oklab(以及较早的 Lab)色彩空间是合适的,因为它们被设计为感知上均匀的。
  • 如果希望在颜色混合中避免变灰,即在整个过渡过程中最大化色度,那么 Oklch(以及较早的 LCH)色彩空间效果很好。
  • 只有当你需要匹配使用 sRGB 的特定设备或软件的行为时,才使用 sRGB。sRGB 色彩空间既不是线性光也不是感知上均匀的,并且会产生较差的结果,例如过度暗淡或灰暗的混合色。

颜色插值方法

<color-interpolation-method> 指定混合颜色时应使用的插值方法。它由 in 关键字和颜色应在其中混合的色彩空间组成。色彩空间必须是形式化语法中列出的可用色彩空间之一。根据所使用的色彩空间,你可以选择性地指定色相沿更长或更短的路径混合。

<rectangular-color-space> 类别包括 srgbsrgb-lineardisplay-p3a98-rgbprophoto-rgbrec2020laboklabxyzxyz-d50xyz-d65

<polar-color-space> 类别包括 hslhwblchoklch。对于这些,你可以在色彩空间名称后选择性地跟随一个 <hue-interpolation-method>。该值默认为 shorter hue,但也可以设置为 longer hueincreasing huedecreasing hue

颜色百分比

两种颜色中的每一种都可以声明一个介于 0%100% 之间的 <percentage> 值,用于指定要混合的相应颜色的量。如果声明的百分比总和不等于 100%,则会对百分比进行规范化处理。

两种颜色的百分比(我们称之为 p1p2)的规范化规则如下:

  • 如果 p1p2 都被省略,那么 p1 = p2 = 50%
  • 如果省略 p1,那么 p1 = 100% - p2
  • 如果省略 p2,那么 p2 = 100% - p1
  • 如果 p1 = p2 = 0%,则函数无效。
  • 如果 p1 + p2 ≠ 100%,那么 p1' = p1 / (p1 + p2) 并且 p2' = p2 / (p1 + p2),其中 p1'p2' 是规范化后的结果。
    • 如果 p1 + p2 < 100%,则会将一个 p1 + p2 的 alpha 乘数应用于结果颜色。这类似于混入 transparent,其百分比为 pt = 100% - p1 - p2

正式语法

<color-mix()> = 
color-mix( <color-interpolation-method>? , [ <color> && <percentage [0,100]>? ]# )

<color-interpolation-method> =
in [ <rectangular-color-space> | <polar-color-space> <hue-interpolation-method>? | <custom-color-space> ]

<rectangular-color-space> =
srgb |
srgb-linear |
display-p3 |
display-p3-linear |
a98-rgb |
prophoto-rgb |
rec2020 |
lab |
oklab |
<xyz-space>

<polar-color-space> =
hsl |
hwb |
lch |
oklch

<hue-interpolation-method> =
[ shorter | longer | increasing | decreasing ] hue

<custom-color-space> =
<dashed-ident>

<xyz-space> =
xyz |
xyz-d50 |
xyz-d65

示例

混合两种颜色

此示例演示了混合两种颜色,红色 #a71e14(以不同百分比)和白色(未指定百分比)。混合的 #a71e14 的百分比越高,输出的颜色就越红,白色就越少。

HTML

html
<ul>
  <li>0%</li>
  <li>25%</li>
  <li>50%</li>
  <li>75%</li>
  <li>100%</li>
  <li></li>
</ul>

CSS

color-mix() 函数用于增加红色的百分比,直到 100%。第 6 个 <li> 没有为任何一种颜色指定百分比。

css
li:nth-child(1) {
  background-color: color-mix(in oklab, #a71e14 0%, white);
}

li:nth-child(2) {
  background-color: color-mix(in oklab, #a71e14 25%, white);
}

li:nth-child(3) {
  background-color: color-mix(in oklab, #a71e14 50%, white);
}

li:nth-child(4) {
  background-color: color-mix(in oklab, #a71e14 75%, white);
}

li:nth-child(5) {
  background-color: color-mix(in oklab, #a71e14 100%, white);
}

li:nth-child(6) {
  background-color: color-mix(in oklab, #a71e14, white);
}

结果

color-mix() 函数中,两种颜色的总值为 100%,即使开发者设置的值总和不为 100%。在此示例中,由于只有一种颜色被分配了百分比,另一种颜色被隐式地赋予了一个百分比值,以使总和等于 100%。在最后一个 <li> 中,两种颜色都未分配百分比,因此它们都默认为 50%。

增加透明度

此示例演示了如何使用 color-mix() 函数通过将任何颜色与 transparent 混合来为颜色增加透明度。

HTML

html
<ul>
  <li>0%</li>
  <li>25%</li>
  <li>50%</li>
  <li>75%</li>
  <li>100%</li>
  <li></li>
</ul>

CSS

color-mix() 函数用于增加 red 的百分比,该颜色使用在 :root 上定义的名为 --base自定义属性声明。第 6 个 <li> 未包含百分比,创建了一个不透明度为 --base 颜色一半的输出颜色。我们在 <ul> 上添加了条纹背景,以使透明度可见。

css
:root {
  --base: red;
}

ul {
  background: repeating-linear-gradient(
    45deg,
    chocolate 0px 2px,
    white 2px 12px
  );
}

li:nth-child(1) {
  background-color: color-mix(in srgb, var(--base) 0%, transparent);
}

li:nth-child(2) {
  background-color: color-mix(in srgb, var(--base) 25%, transparent);
}

li:nth-child(3) {
  background-color: color-mix(in srgb, var(--base) 50%, transparent);
}

li:nth-child(4) {
  background-color: color-mix(in srgb, var(--base) 75%, transparent);
}

li:nth-child(5) {
  background-color: color-mix(in srgb, var(--base) 100%, transparent);
}

li:nth-child(6) {
  background-color: color-mix(in srgb, var(--base), transparent);
}

结果

通过这种方式,color-mix() 函数可以用于为任何颜色增加透明度,即使该颜色本身已经是不完全不透明的(alpha 通道值小于 1)。但是,color-mix() 不能用于使半透明颜色完全不透明。为此,请使用带有 CSS 颜色函数相对颜色。相对颜色可以改变任何颜色通道的值,包括增加颜色的 alpha 通道以使颜色完全不透明。

在 color-mix() 中使用色相插值

此示例演示了 color-mix() 函数可用的色相插值方法。当使用色相插值时,结果的色相介于被混合的两种颜色的色相值之间。根据在色轮上所选的路径,该值会有所不同。

更多信息,请参阅 <hue-interpolation-method>

CSS

shorter hue 插值方法沿色轮走较短的路径,而 longer hue 插值方法则走较长的路径。使用 increasing hue 时,路径从增加的值开始。使用 decreasing hue 时,值会减少。我们混合两种 <named-color> 值来创建一系列 lch() 中间色,这些颜色根据在色轮上所选的路径而不同。混合的颜色包括 redblueyellow,其 LCH 色相值分别约为 41deg、301deg 和 100deg。

为了减少代码冗余,我们对颜色和插值方法都使用了 CSS 自定义属性,并在每个 <ul> 上设置了不同的值。

css
ul:nth-of-type(1) {
  --distance: longer; /* 52 degree hue increments */
  --base: red;
  --mixin: blue;
}
ul:nth-of-type(2) {
  /* 20 degree hue decrements */
  --distance: shorter;
  --base: red;
  --mixin: blue;
}
ul:nth-of-type(3) {
  /* 40 degree hue increments */
  --distance: increasing;
  --base: yellow;
  --mixin: blue;
}
ul:nth-of-type(4) {
  /* 32 degree hue decrements */
  --distance: decreasing;
  --base: yellow;
  --mixin: blue;
}

li:nth-child(1) {
  background-color: color-mix(
    in lch var(--distance) hue,
    var(--base) 100%,
    var(--mixin)
  );
}

li:nth-child(2) {
  background-color: color-mix(
    in lch var(--distance) hue,
    var(--base) 80%,
    var(--mixin)
  );
}

li:nth-child(3) {
  background-color: color-mix(
    in lch var(--distance) hue,
    var(--base) 60%,
    var(--mixin)
  );
}

li:nth-child(4) {
  background-color: color-mix(
    in lch var(--distance) hue,
    var(--base) 40%,
    var(--mixin)
  );
}

li:nth-child(5) {
  background-color: color-mix(
    in lch var(--distance) hue,
    var(--base) 20%,
    var(--mixin)
  );
}

li:nth-child(6) {
  background-color: color-mix(
    in lch var(--distance) hue,
    var(--base) 0%,
    var(--mixin)
  );
}

结果

使用 longer hue 时,颜色之间的增量或减量将总是等于或大于使用 shorter hue 时的值。当色相值变化的方向比值之间的距离更重要时,请使用 increasing huedecreasing hue

规范

规范
CSS 颜色模块第五版
# color-mix

浏览器兼容性

另见