写过设计系统的人都踩过这个坑——每次加个透明度都要重新定义一套色值,今天 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 的自动更新,正在让这件事变得越来越不是问题。
评论区
登录后可评论。