颜色调不准,CSS里有没有像调色盘一样混颜色的方法?

2,267字
10–14 分钟
in

在CSS里折腾颜色,以前想搞个半透明或者混合色,要么算十六进制,要么用PS取色,麻烦得一批。现在好了,浏览器原生支持几种骚操作,直接把两种颜色丢进去,就能吐出新色号。不管是纯黑纯白,还是什么奇怪的名字色,都能像画画调颜料一样整活。下面直接上干货,看完就能上手玩颜色混合。

目录

基础混色函数

color-mix()这玩意儿就是官方的调色盘。给两个颜色值,再指定各自占多少比例,浏览器自动算出混合后的颜色。比如想把黑色和白色兑成灰色,直接写color-mix(#000 30%, #fff 70%),出来就是30%黑加70%白的灰。比例不写的话默认五五开。这函数支持所有合法颜色格式,十六进制、rgb、hsl、甚至rebeccapurple这种名字色通吃。

下面是一套完整操作流程,拿背景色演示怎么调出想要的中度灰:

/* 目标:调一个偏冷色调的浅灰,不用自己算hex */
.demo-box {
  /* 方案A:黑加白,黑占两成,白占八成 */
  background-color: color-mix(in srgb, #000 20%, #fff 80%);

  /* 方案B:用蓝灰色和白色混合,更冷一点 */
  background-color: color-mix(in srgb, #6c8ebf 15%, #fff 85%);
}

在实际开发里,比如做按钮悬浮态,原来背景是#2a6f8f,想让它变深15%同时带点透明度。可以用color-mix掺黑色和半透白:

.btn {
  background-color: #2a6f8f;
}
.btn:hover {
  /* 原色混合15%的纯黑,变暗 */
  background-color: color-mix(in srgb, #2a6f8f 85%, #000 15%);
}

跑这段代码时,浏览器会自动计算混合结果,完全不用操心色值转换。需要留意color-mix的第一个参数是颜色空间,in srgb最常用,想玩高级的可以换成in hslin oklab,不同空间混出来的视觉效果有细微差别。如果混出来的颜色偏灰不精神,试试切换颜色空间,比如in oklab更贴合人眼感知。

动画叠色技巧

另一种更野的路子,用animation-compositionadd值来实时混合颜色。这属性本来控制关键帧动画怎么叠加效果,但把add用上后,动画里的颜色会和元素原本的背景色加在一起,产生新的混合色。相比color-mix的静态计算,这玩意儿能做出动态渐变的混合效果,比如悬浮时颜色从A慢慢变成A+B的混合态。

具体开干流程如下,目标是让一个蓝色方块悬浮时平滑过渡到蓝绿混合色:

第一步,写一个基础样式,背景设成纯蓝色:

.mix-box {
  width: 200px;
  height: 200px;
  background-color: #1e88e5; /* 基础蓝 */
  transition: all 0.2s;
}

第二步,定义一个关键帧动画,里面放绿色作为效果值:

@keyframes blendGreen {
  from { background-color: #4caf50; }
  to { background-color: #4caf50; }
}

第三步,在悬浮态把动画绑上去,并把animation-composition设为add

.mix-box:hover {
  animation: blendGreen 1s infinite alternate;
  animation-composition: add;
}

此时悬浮在盒子上,蓝色底和绿色动画会叠加混合,肉眼看到一种介于蓝绿之间的新颜色。add的工作逻辑是:不替换原本的background-color,而是把关键帧里的颜色值按通道加起来。比如蓝色R=30 G=136 B=229,绿色R=76 G=175 B=80,相加后超出255的会被截断,最终得到一个偏亮的青色调。

想精确拿到混合后的色值,可以用浏览器开发工具。鼠标悬浮元素,打开“检查”,在“计算后样式”面板里找background-color,浏览器会显示最终的RGB数值。比如上面例子混合后可能显示为rgb(106, 255, 255)附近。把这个数值复制出来,就能用在其他地方。

对比color-mixanimation-composition add更适合做动态过渡效果,但要注意:动画的tofrom如果一样,动画其实没变化,但add依然会把那个固定颜色持续叠加上去。另一个坑是animation-composition目前在一些旧版浏览器不支持,可以用@supports做回退:

@supports (animation-composition: add) {
  .mix-box:hover {
    animation: blendGreen 1s infinite;
    animation-composition: add;
  }
}
@supports not (animation-composition: add) {
  .mix-box:hover {
    background-color: color-mix(in srgb, #1e88e5 50%, #4caf50 50%);
  }
}

两种方案对比一下:

方案适用场景浏览器要求
color-mix静态混色较新都支持
add叠色动态混合需2023后版本

搞颜色混合不用再怕计算器按烂,color-mix一把梭搞定静态调色,animation-composition add适合玩花里胡哨的动态渐变。碰到名字色要加透明度,也可以用相对颜色语法hsl(from rebeccapurple h s l / 50%),直接给不透明的颜色加上半透明层。这些招数混着用,页面配色基本横着走。