CSS color-mix函数完全指南:不用JS也能调色

更新日期: 2026-04-12 阅读: 48 标签: 颜色

以前做颜色变体要写很多代码,现在CSS原生支持color-mix,让你直接在样式表里混合颜色。主题色、悬浮色、半透明效果,一行代码就能搞定。


你以前是怎么做颜色变体的

做一套按钮组件,需要hover色、禁用色、浅色背景,以前的写法是这样的:

.btn {
  background: #3b82f6;
}
.btn:hover {
  background: #2563eb;
}
.btn:disabled {
  background: #93c5fd;
}

或者用SCSS的darken和lighten函数,但那些需要构建工具。

现在原生CSS有了color-mix,不用那么麻烦了。


基础语法

color-mix(in <颜色空间>, 颜色A <百分比>, 颜色B <百分比>)

颜色空间有srgb、hsl、oklch、lab等。推荐用oklch,这种颜色空间感知比较均匀,混出来的效果最自然。

百分比是指颜色A占多少比例,颜色B占剩下的。两个百分比加起来不需要等于100%。

/* 蓝色和白色各一半,得到浅蓝色 */
color: color-mix(in srgb, #3b82f6 50%, white);

/* 蓝色加30%黑色,得到深蓝色 */
color: color-mix(in srgb, #3b82f6, black 30%);

/* 蓝色加透明,得到半透明效果 */
background: color-mix(in srgb, #3b82f6 60%, transparent);

浏览器兼容性

浏览器支持版本发布时间
Chrome111+2023年3月
Firefox113+2023年5月
Safari16.2+2022年12月
Edge111+2023年3月

2023年底开始可以放心在生产环境使用,全球覆盖率超过90%。


实战1:用CSS变量做主题色系

只定义一个主色,自动生成深色、浅色、半透明版本:

:root {
  --primary: #3b82f6;

  /* 自动生成色系,不用手动调色了 */
  --primary-dark:    color-mix(in oklch, var(--primary), black 20%);
  --primary-darker:  color-mix(in oklch, var(--primary), black 40%);
  --primary-light:   color-mix(in oklch, var(--primary), white 40%);
  --primary-lighter: color-mix(in oklch, var(--primary), white 70%);
  --primary-alpha-20: color-mix(in srgb, var(--primary) 20%, transparent);
  --primary-alpha-10: color-mix(in srgb, var(--primary) 10%, transparent);
}

.btn {
  background: var(--primary);
  color: white;
}

.btn:hover {
  background: var(--primary-dark);
}

.btn:active {
  background: var(--primary-darker);
}

.btn:disabled {
  background: var(--primary-lighter);
  color: var(--primary-light);
  cursor: not-allowed;
}

.btn-ghost {
  background: var(--primary-alpha-10);
  color: var(--primary);
  border: 1px solid var(--primary-alpha-20);
}

.btn-ghost:hover {
  background: var(--primary-alpha-20);
}

换主题色只需要改--primary这一个变量,整套色系都会跟着变。


实战2:动态悬浮色

不用再硬编码每个颜色的hover效果了:

/* 任意颜色的卡片,hover时自动加深 */
.card {
  --card-color: #10b981;
  background: var(--card-color);
  transition: background 0.2s;
}

.card:hover {
  background: color-mix(in oklch, var(--card-color), black 15%);
}

/* 多彩标签,hover色自动计算 */
.tag {
  --tag-bg: #f59e0b;
  background: color-mix(in srgb, var(--tag-bg) 15%, transparent);
  color: color-mix(in oklch, var(--tag-bg), black 30%);
  border: 1px solid color-mix(in srgb, var(--tag-bg) 40%, transparent);
}

.tag:hover {
  background: color-mix(in srgb, var(--tag-bg) 25%, transparent);
}

实战3:暗色模式颜色适配

:root {
  --bg: white;
  --text: #1f2937;
  --border: #e5e7eb;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #111827;
    --text: #f9fafb;
    --border: #374151;
  }
}

.card {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
}

/* 暗色模式下卡片头部自动用半透明白色叠加 */
.card .card-header {
  background: color-mix(in srgb, var(--text) 5%, transparent);
}

.card:hover {
  /* 亮色模式变深,暗色模式变浅,同一行代码两个效果都正确 */
  background: color-mix(in srgb, var(--bg), var(--text) 5%);
}

实战4:渐变色中间色计算

需要手写渐变但不知道中间色是什么,color-mix可以直接算出来:

.gradient-banner {
  --start: #6366f1;
  --end: #ec4899;

  /* 手动计算中间色 */
  --mid: color-mix(in oklch, var(--start) 50%, var(--end));

  background: linear-gradient(
    135deg,
    var(--start) 0%,
    var(--mid) 50%,
    var(--end) 100%
  );
}

/* 更细腻的5步渐变 */
.gradient-5 {
  --c1: #3b82f6;
  --c2: #8b5cf6;
  background: linear-gradient(
    to right,
    var(--c1),
    color-mix(in oklch, var(--c1) 75%, var(--c2)),
    color-mix(in oklch, var(--c1) 50%, var(--c2)),
    color-mix(in oklch, var(--c1) 25%, var(--c2)),
    var(--c2)
  );
}

完整可运行Demo

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>color-mix函数演示</title>
<style>
  * { box-sizing: border-box; margin: 0; padding: 0; }
  body { font-family: sans-serif; background: #f8fafc; padding: 32px; }

  /* 动态主题色系 */
  .theme-demo {
    --primary: #6366f1;
    --primary-dark:    color-mix(in oklch, var(--primary), black 20%);
    --primary-light:   color-mix(in oklch, var(--primary), white 50%);
    --primary-lighter: color-mix(in oklch, var(--primary), white 80%);
    --primary-alpha:   color-mix(in srgb, var(--primary) 15%, transparent);

    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 24px;
  }

  .swatch {
    width: 80px;
    height: 80px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 600;
    color: white;
  }

  .s1 { background: var(--primary-dark);    color: white; }
  .s2 { background: var(--primary);         color: white; }
  .s3 { background: var(--primary-light);   color: white; }
  .s4 { background: var(--primary-lighter); color: var(--primary-dark); }
  .s5 { background: var(--primary-alpha);   color: var(--primary-dark); border: 1px solid var(--primary-light); }

  /* 按钮演示 */
  .btn-row { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 24px; }

  .btn {
    --c: #3b82f6;
    padding: 10px 20px;
    border: none;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, transform 0.1s;
  }
  .btn.solid {
    background: var(--c);
    color: white;
  }
  .btn.solid:hover {
    background: color-mix(in oklch, var(--c), black 18%);
  }
  .btn.solid:active {
    transform: scale(0.97);
  }

  .btn.ghost {
    background: color-mix(in srgb, var(--c) 12%, transparent);
    color: var(--c);
    border: 1.5px solid color-mix(in srgb, var(--c) 35%, transparent);
  }
  .btn.ghost:hover {
    background: color-mix(in srgb, var(--c) 22%, transparent);
  }

  .btn.green { --c: #10b981; }
  .btn.red   { --c: #ef4444; }

  /* 渐变演示 */
  .gradient-bar {
    --c1: #3b82f6;
    --c2: #ec4899;
    height: 48px;
    border-radius: 10px;
    background: linear-gradient(
      to right,
      var(--c1),
      color-mix(in oklch, var(--c1) 75%, var(--c2)),
      color-mix(in oklch, var(--c1) 50%, var(--c2)),
      color-mix(in oklch, var(--c1) 25%, var(--c2)),
      var(--c2)
    );
  }

  h3 { margin-bottom: 12px; color: #374151; font-size: 14px; }
</style>
</head>
<body>
  <h3>主题色系(只有一个主色变量)</h3>
  <div class="theme-demo">
    <div class="swatch s1">深色</div>
    <div class="swatch s2">主色</div>
    <div class="swatch s3">浅色</div>
    <div class="swatch s4">更浅</div>
    <div class="swatch s5">半透明</div>
  </div>

  <h3>按钮悬浮色自动计算</h3>
  <div class="btn-row">
    <button class="btn solid">蓝色按钮</button>
    <button class="btn solid green">绿色按钮</button>
    <button class="btn solid red">红色按钮</button>
    <button class="btn ghost">Ghost按钮</button>
    <button class="btn ghost green">Ghost绿</button>
  </div>

  <h3>color-mix计算渐变中间色</h3>
  <div class="gradient-bar"></div>
</body>
</html>

选哪个颜色空间

颜色空间特点推荐用途
srgb传统RGB混色,速度快透明度变体(加transparent)
hsl色相饱和度亮度,直观色轮旋转、互补色
oklch感知均匀,亮度一致主题色深浅变体,首选
lab科学级感知均匀精确色差计算

经验法则:加深加浅用oklch,加透明用srgb。


总结

场景以前的做法现在的做法
生成hover颜色手动挑色或用SCSS的darken函数color-mix(in oklch, var(--c), black 15%)
生成半透明色rgba(59, 130, 246, 0.2)color-mix(in srgb, #3b82f6 20%, transparent)
多彩组件色系每个颜色写4到5个变量一个主色变量,其余自动推导
渐变中间色凭感觉猜color-mix精确计算

color-mix是目前CSS原生颜色操作中最实用的函数。配合CSS变量一起用,设计系统的实现会优雅很多。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/13610

相关推荐

常用颜色表之中国传统颜色

不知道大家觉得如何,舒适的颜色,很多人都会喜欢,但主要还是看实用性。今天给大家分享中国传统颜色有那些?中国传统的颜色之美,美如其名:蔚蓝、竹青、绯红、月白、石青、紫檀、霜色、黛绿、胭脂、藕荷、豆绿、宝蓝、秋香、玄色、牙色、黄栌、靛蓝、明黄、朱砂、石绿

Js计算颜色对比度

某些网站和服务允许您通过上传图片,更改背景颜色或设计的其他方面来自定义您的个人资料。作为客户,此个性化将Web应用程序转换为您存储数据的小窝。

css中颜色

假设在设置页面的颜色时觉得一部分很小的颜色集中就足够了,就可以直接给定颜色的名称。CSS称这些有名称的颜色为命名颜色。命名颜色的关键字有限,css定义了17个标准色:浅绿色,黑色,蓝色

css颜色模式hsla和rgba

在CSS3中可以使用RGBA和HSLA两种色彩模式,这两个都可以用来设置颜色以及指定透明度。RGBA无法直观看出是什么颜色。并且如果想要对颜色进行调整也无法简单做到

原生JS代码实现随机产生一个16进制的颜色值

封装一个函数,一个十六进制的值的数组,产生的每个随机数都是一个索引,根据索引找到数组中对应的值,拼接到一起,调用函数getColor()就能随机获取一个16进制的颜色值

HTML常用的颜色表【代码色彩表 】

以下是DIVCSS5整理常用的HTML颜色表,参考,直接找到自己需要的html颜色值拷贝颜色值代码即可使用(除了以下颜色表外,你还可以使用PS软件获取颜色值:http://www.divcss5.com/html/h635.shtml)。

RGB、HSL、Hex网页色彩码,看完这篇全懂了

网页使用到的色彩标示方法中,从古早时期大家都在用的16进位码(#000000)、RGB色值标示、HSL色彩标示,其中网页设计师最常使用的16进位色码标示法,而16进位码又是如何计算色彩的呢?

vue在线动态切换主题色方案

主要原理是利用webpack插件webpack-theme-color-replacer提取相关颜色css然后根据配置动态生成替换的css,具体实现步骤如下:

css常用的颜色单位表示法

所有的颜色都可以由红、绿、蓝三原色调配而成。 CSS中用8位表示一个颜色,那么可以有28即256种颜色,所以总共可以表示256*256*256种颜色。CSS纵有多种颜色表示: 十六进制表示法、rgb表示法、hsl色相表示法、hsla色相表示法

ios input disabled 字体颜色修改无效

设置 input:disabled 的字体颜色,在 ios下无效,颜色很暗。pc端显示正常。iPhone Safari/webview 环境下 input disabled 的默认样式会有默认样式opacity以及隐藏样式-webkit-text-fill-color

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!