CSS `color-mix()` `space` 参数:在不同颜色空间进行颜色混合

早上好,各位颜色爱好者,今天我们来聊聊CSS color-mix() 中那个神秘又强大的 space 参数。

开场白:颜色,不仅仅是RGB

大家平时写CSS,颜色是不是 redblue#ffffff 这样直接招呼? 或者更高级一点,用 rgba() 加上透明度? 没毛病! 但颜色世界远比你想象的精彩。它不仅仅是红绿蓝的简单组合,还涉及色彩的感知、物理特性,以及各种数学模型。color-mix() 函数的 space 参数,就是打开这个精彩世界的一把钥匙。

color-mix() 基础回顾:先学会走路,才能跑

在深入 space 参数之前,咱们先快速回顾一下 color-mix() 的基本用法。这就像学开车前,先得知道方向盘和油门在哪儿。

color-mix() 函数的基本语法是:

color-mix( in <color-space>, <color> <percentage>?, <color> <percentage>? )
  • <color-space>: 这就是我们今天要重点讨论的 space 参数,指定颜色混合发生的颜色空间。
  • <color>: 参与混合的颜色。可以是任何有效的 CSS 颜色值,比如 red, #00ff00, rgb(255, 0, 0), hsl(0, 100%, 50%) 等等。
  • <percentage>: 可选参数,指定颜色的混合比例。如果没有指定,默认情况下颜色将以 50/50 的比例混合。

举个栗子:

.my-element {
  background-color: color-mix(in srgb, red 50%, blue 50%); /* 混合红色和蓝色,各占50% */
}

.another-element {
  background-color: color-mix(in srgb, red, blue); /* 效果同上,默认50/50 */
}

.yet-another-element {
  background-color: color-mix(in srgb, red 20%, blue 80%); /* 红色占20%,蓝色占80% */
}

上面的例子都使用了 srgb 颜色空间。 接下来,才是重头戏。

space 参数:颜色空间的奥秘

space 参数决定了颜色混合发生的数学模型。不同的颜色空间,对颜色的定义和感知方式不同,混合的结果也会大相径庭。 想象一下,同样是“红色”和“蓝色”,在不同的画家的调色盘里,混合出来的紫色可能千差万别。

CSS 规范中定义了以下几种颜色空间(截止目前,可能随着规范更新会有增删):

  1. srgb (Standard RGB): 这是最常见的颜色空间,也是网页中最常用的。它基于红、绿、蓝三原色,简单直接,兼容性好。但 srgb 在颜色感知上并非线性,也就是说,数值上的线性变化,并不一定对应人眼感知的线性变化。

  2. srgb-linear: srgb 的线性版本。它修正了 srgb 的非线性问题,使数值上的变化与人眼感知的变化更加一致。在进行颜色混合时,srgb-linear 通常能产生更自然、更平滑的过渡。

  3. lab: 基于人眼感知的颜色空间,更符合人类视觉的特性。lab 将颜色分解为 L(亮度)、a(绿-红轴)、b(蓝-黄轴)三个分量。 lab 在颜色混合时,通常能产生更符合直觉的结果,避免出现一些在 srgb 中可能出现的“脏色”或“不和谐”的颜色。 lab 的优点是色彩范围广阔,能表示比 srgb 更多的颜色。

  4. oklab: lab 的改进版本,解决了 lab 在某些情况下可能出现的色相偏移问题。oklab 在颜色感知上更加均匀,混合效果也更加自然。被认为是目前在颜色处理方面最佳的颜色空间之一。

  5. lch: 与 lab 类似,也是基于人眼感知的颜色空间。lch 将颜色分解为 L(亮度)、C(彩度)、H(色相)三个分量。lch 的优点是可以独立控制颜色的亮度、彩度和色相,方便进行色彩调整。

  6. oklch: lch 的改进版本,与 oklab 类似,解决了 lch 在某些情况下可能出现的色相偏移问题,并且在感知均匀性方面表现更好。

  7. display-p3: 一种广色域颜色空间,能表示比 srgb 更多的颜色。display-p3 常用于高色彩要求的显示设备,比如高端显示器和移动设备。

  8. rec2020: 另一种广色域颜色空间,比 display-p3 还要广。rec2020 常用于超高清电视和电影制作。

代码示例:颜色空间的对比实验

光说不练假把式,咱们直接上代码,看看不同颜色空间混合出来的效果有什么不同。

<!DOCTYPE html>
<html>
<head>
<title>Color-mix Space Demo</title>
<style>
  .color-box {
    width: 100px;
    height: 100px;
    margin: 10px;
    display: inline-block;
  }

  .srgb {
    background-color: color-mix(in srgb, red 50%, blue 50%);
  }

  .srgb-linear {
    background-color: color-mix(in srgb-linear, red 50%, blue 50%);
  }

  .lab {
    background-color: color-mix(in lab, red 50%, blue 50%);
  }

  .oklab {
    background-color: color-mix(in oklab, red 50%, blue 50%);
  }

  .lch {
    background-color: color-mix(in lch, red 50%, blue 50%);
  }

  .oklch {
    background-color: color-mix(in oklch, red 50%, blue 50%);
  }

  .display-p3 {
    background-color: color-mix(in display-p3, red 50%, blue 50%);
  }

  .rec2020 {
    background-color: color-mix(in rec2020, red 50%, blue 50%);
  }

  .description {
    font-size: 12px;
    text-align: center;
  }
</style>
</head>
<body>

  <div class="color-box srgb"></div>
  <div class="description">srgb</div>

  <div class="color-box srgb-linear"></div>
  <div class="description">srgb-linear</div>

  <div class="color-box lab"></div>
  <div class="description">lab</div>

  <div class="color-box oklab"></div>
  <div class="description">oklab</div>

  <div class="color-box lch"></div>
  <div class="description">lch</div>

  <div class="color-box oklch"></div>
  <div class="description">oklch</div>

  <div class="color-box display-p3"></div>
  <div class="description">display-p3</div>

  <div class="color-box rec2020"></div>
  <div class="description">rec2020</div>

</body>
</html>

把这段代码复制到你的 HTML 文件里,用浏览器打开,你就能看到不同颜色空间混合出来的颜色了。仔细观察,你会发现 srgbsrgb-linear 的紫色比较接近,但 srgb-linear 稍微柔和一点。laboklablchoklch 的紫色则更加鲜艳、纯正。 display-p3rec2020 如果你的显示器支持广色域,那么它们显示的紫色会更加饱和,如果不支持,可能会和srgb颜色空间的结果很接近。

颜色空间的具体应用场景

不同的颜色空间有不同的特点,适用于不同的场景。 选择合适的颜色空间,可以让你在颜色处理方面事半功倍。

颜色空间 优点 缺点 适用场景
srgb 兼容性好,简单易用。 颜色感知非线性,混合结果可能不符合直觉。色彩范围较窄。 网页设计,简单颜色混合,不需要特别精确的颜色控制。
srgb-linear 修正了 srgb 的非线性问题,混合结果更自然。 兼容性不如 srgb 网页设计,需要更平滑的颜色过渡,例如渐变。
lab 基于人眼感知,颜色混合结果更符合直觉。色彩范围广阔。 计算复杂,性能稍差。在某些情况下可能出现色相偏移(已被 oklab 解决)。 需要精确颜色控制的设计,例如品牌颜色定义、图像处理。
oklab 解决了 lab 的色相偏移问题,颜色感知更加均匀。被认为是目前最佳的颜色空间之一。 计算复杂,性能稍差。兼容性不如 srgb 需要高质量颜色混合的场景,例如复杂渐变、颜色动画。也适用于需要保证颜色一致性的场景。
lch 可以独立控制颜色的亮度、彩度和色相,方便进行色彩调整。 计算复杂,性能稍差。在某些情况下可能出现色相偏移(已被 oklch 解决)。 需要灵活调整颜色的设计,例如主题颜色定制、数据可视化。
oklch 解决了 lch 的色相偏移问题,并且在感知均匀性方面表现更好。 计算复杂,性能稍差。兼容性不如 srgb 需要高质量颜色混合和灵活颜色调整的场景。例如动态主题颜色生成、高级图像处理。
display-p3 广色域,能表示比 srgb 更多的颜色。 需要显示设备支持广色域才能发挥优势。兼容性不如 srgb 高色彩要求的显示设备,例如高端显示器和移动设备。适用于需要展示更丰富色彩的场景,例如摄影作品展示、游戏。
rec2020 广色域,比 display-p3 还要广。 需要显示设备支持广色域才能发挥优势。兼容性最差。 超高清电视和电影制作。适用于对色彩还原度要求极高的场景。

一些注意事项和最佳实践

  • 兼容性: color-mix() 函数和 space 参数是相对较新的 CSS 特性,一些老版本的浏览器可能不支持。 在使用时,最好进行兼容性测试,并提供 fallback 方案。比如,可以使用 @supports 查询来判断浏览器是否支持 color-mix(),如果不支持,则使用传统的颜色定义方式。

    .my-element {
      background-color: purple; /* Fallback color */
    }
    
    @supports (background-color: color-mix(in srgb, red, blue)) {
      .my-element {
        background-color: color-mix(in srgb, red, blue);
      }
    }
  • 性能: laboklablchoklch 等颜色空间的计算比较复杂,可能会影响页面性能。 在性能敏感的场景下,需要谨慎使用。

  • 色彩管理: 广色域颜色空间需要显示设备的支持才能发挥优势。 如果显示设备不支持广色域,那么 display-p3rec2020 的颜色可能会被裁剪到 srgb 范围内,导致颜色失真。

  • 设计原则: 颜色混合不仅仅是技术问题,也是设计问题。 在选择颜色空间和混合比例时,需要考虑整体的视觉效果和用户体验。 避免使用过于刺眼或不和谐的颜色组合。

高级技巧:超越简单的混合

color-mix()space 参数不仅仅可以用于简单的颜色混合,还可以用于实现一些更高级的效果。

  • 创建平滑的渐变: 使用 srgb-linearlaboklab 等颜色空间,可以创建更平滑、更自然的渐变。

    .gradient {
      background: linear-gradient(to right, color-mix(in oklab, red, white), color-mix(in oklab, blue, white));
    }
  • 动态调整颜色: 结合 CSS 变量和 JavaScript,可以动态调整颜色混合的比例和颜色空间,实现一些有趣的颜色动画效果。

    <!DOCTYPE html>
    <html>
    <head>
    <title>Dynamic Color Mix</title>
    <style>
      :root {
        --mix-ratio: 50%;
      }
    
      .dynamic-color {
        width: 200px;
        height: 200px;
        background-color: color-mix(in oklch, red var(--mix-ratio), blue calc(100% - var(--mix-ratio)));
      }
    </style>
    </head>
    <body>
    
      <div class="dynamic-color"></div>
    
      <input type="range" min="0" max="100" value="50" oninput="document.documentElement.style.setProperty('--mix-ratio', this.value + '%')">
    
    </body>
    </html>
  • 创建主题颜色: 可以使用 color-mix()lchoklch 颜色空间,基于一个基准颜色,生成一系列的主题颜色,例如亮色、暗色、强调色等。

总结:颜色,是一门艺术,也是一门科学

color-mix() 函数的 space 参数,让我们能够更深入地探索颜色的奥秘,创造出更丰富、更精彩的视觉效果。 它不仅仅是一个技术细节,更是一种设计理念,一种对色彩的理解和掌控。

希望今天的讲座能帮助大家更好地理解 color-mix()space 参数,并在实际项目中灵活运用。记住,颜色不仅仅是代码,更是一种表达,一种情感,一种艺术。 掌握了颜色,你就掌握了设计的灵魂。

感谢大家的聆听! 下次有机会,我们再一起探索 CSS 的其他精彩特性。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注