写过设计系统的人都踩过这个坑——每次加个透明度都要重新定义一套色值,今天 CSS alpha() 把这件事彻底原生化了

做过设计系统的工程师大概都踩过这个坑——主色定了,但按钮的悬停太深、卡片背景要浅一点、遮罩层要更透,每一种透明度都要在设计系统里硬编码一条新色值。改一次主色,整套透明变体全要跟着动。

CSS Color Level 5 里的 alpha() 函数,就是来解决这个问题的。

一句话说明

alpha(from <颜色> / <透明度>) 从已有颜色里提取 alpha 通道,直接输出一个新的透明变体,不需要拆通道、不需要手动算 hex。

实际怎么用

最直接的两个场景:

设计系统透明变体,一行搞定

/ 以前:每种透明度都要单独定义 /
–btn-primary-bg: #3366ff;
–btn-primary-bg-80: rgb(51 102 255 / 0.8);
–btn-primary-bg-50: rgb(51 102 255 / 0.5);
–btn-primary-bg-20: rgb(51 102 255 / 0.2);

/ 以后:只定义主色,透明变体自动派生 /
–btn-primary-bg: #3366ff;
–btn-primary-bg-80: alpha(from var(–btn-primary-bg) / 80%);
–btn-primary-bg-50: alpha(from var(–btn-primary-bg) / 50%);
–btn-primary-bg-20: alpha(from var(–btn-primary-bg) / 20%);
改一行 –btn-primary-bg,所有派生变体自动更新,不需要人肉追踪哪里用了什么透明度。

悬停状态,直接引用当前色做半透明

.card {
background: alpha(from var(–card-bg) / 80%);
}
.card:hover {
/ 悬停时背景加深到 95% 不透明度,文本颜色不变 /
background: alpha(from var(–card-bg) / 95%);
}
以前这个要靠两个独立 token(–card-bg 和 –card-bg-hover),现在同一个 token 加一行搞定。

在 calc() 里引用原始 alpha 值

/ 把当前色的透明度减半 /
alpha(from var(–brand-color) / calc(alpha * 0.5))

/ 限制 alpha 在某个范围内 /
alpha(from var(–surface) / clamp(0.2, alpha, 0.8))
alpha 这个关键字在函数内部代表原始颜色的透明度值,可以做四则运算和 clamp 限制。

对比一下以前怎么做的

方案
问题

手动写 hex:#3366ffcc
肉眼算十六进制,容易出错

Sass 变量:lighten($color, 20%)
需要编译,不是真正的 CSS

CSS 变量拆 RGB:–r: 51; –g: 102; –b: 255;
变量碎片化,维护成本高

alpha()
原生 CSS,变量集中,透明变体自动派生

浏览器支持

Chrome 151+(2026年7月底)和 Firefox 155+(2026年9月)已支持,Safari 暂不支持,属于渐进增强场景。用 @supports 做降级即可:

.button {
background: rgba(51, 102, 255, 0.5); / Safari 降级 /
background: alpha(from var(–brand) / 50%); / Chrome/Firefox /
}
覆盖不了 Safari 用户的时候,降级到 rgba;在支持的浏览器里,享受原生语法的清爽。

怎么迁入现有项目

三步走:

第一步:把主色收拢到变量
确保你的 –brand/–surface 这些核心颜色用的是完整色值,不是拆散的 RGB 通道。

第二步:替换显式透明色
找到项目中 rgba(…) 、#xxxxxx80 这样的透明变体,替换成 alpha(from var(–xxx) / 80%)。

第三步:加 @supports 渐进增强
加一行 rgba 降级,生产里先跑起来,后续浏览器升级自动切换。

设计系统里每加一个透明度就要维护一条新色值,这个坑迟早要填。alpha() 把这件事从「手动维护」变成了「自动派生」,改一行主色,所有透明变体自动跟上。不需要任何构建步骤,不需要 Sass,只需要浏览器版本够新——而 Chrome 和 Firefox 的自动更新,正在让这件事变得越来越不是问题。

评论区

0 条评论

登录后可评论。