你以为调透明度只能靠 color-mix?今天 CSS alpha() 把这件事彻底原生化了
配设计系统配了五年,每次想从一个主色派生出半透明版本,都要先把完整颜色函数抄一遍——否则改透明度只能靠浏览器渲染结果「大概差不多」。Firefox 156 现在把这件事用一个函数彻底原生化了。
以前怎么调透明度
CSS 调透明度最直觉的办法是直接写 alpha 值:
--brand: oklch(55% 0.22 270);
.button { background: oklch(55% 0.22 270 / 50%); }
这没问题,前提是你把完整颜色值直接写进去了。如果颜色来自 CSS 变量,事情就麻烦了:
/* 旧方法:用相对颜色语法,需要把三个通道都列出来 */
--brand: oklch(55% 0.22 270);
/* 50% 透明度的 brand */
.button-ghost {
background: oklch(from var(--brand) l c h / 50%);
/* 三个通道 l、c、h 都要手写,不能省略 */
}
color-mix 也能做,但逻辑完全不同——它把两个颜色混在一起,而不是单纯改透明度:
/* color-mix 把 brand 和透明混,视觉结果是偏灰,不是纯透明 */
.button-ghost {
background: color-mix(in oklch, var(--brand) 50%, transparent);
}
这条 CSS 结果不是「50% 透明的品牌色」,而是「50% 品牌的颜色 + 50% 透明」的混合,在暗色模式下会明显偏灰。
alpha() 登场:只改透明度,其他不动
Firefox 156 稳定支持了 CSS Color Module Level 5 的 alpha() 函数,语法简洁到只有一行:
--brand: oklch(55% 0.22 270);
/* 固定值:50% 透明度 */
.button-ghost { background: alpha(from var(--brand) / 50%); }
/* 相对值:原色透明度的 40% */
.card:hover { background: alpha(from var(--brand) / calc(alpha * 0.4)); }
/* 夹取:透明度不低于 20% 不高于 80% */
.overlay { background: alpha(from var(--brand) / clamp(0.2, alpha, 0.8)); }
三行核心差异:
- 不需要写 l、c、h:颜色通道保持原样,只碰 alpha
- 保留原始色彩空间:brand 是 oklch,结果也是 oklch,不会被强制转 sRGB
- alpha 关键字可用 calc:可以从原透明度派生,不是只能写死数值
对比:三种方案怎么选
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 固定透明度派生 | alpha(from var(–brand) / 50%) | 语义最清晰,只改 alpha |
| 相对原透明度缩放 | alpha(from var(–brand) / calc(alpha * 0.4)) | 利用 alpha 关键字 |
| 透明度夹取 | alpha(from var(–brand) / clamp(0.2, alpha, 0.8)) | 防止过度透明 |
| 颜色混合做透明效果 | color-mix(in oklch, var(–brand) 30%, transparent) | 混合做半透明遮罩 |
| 旧项目快速兼容 | oklch(from var(–brand) l c h / 50%) | 通用写法,各浏览器均支持 |
浏览器支持现状
alpha() 目前处于「Limited availability」状态,不算 Baseline:
- Chrome 151+(含 Android WebView)
- Firefox 155+(含 Firefox Android)预览支持
- Safari 27+ 预览支持
- 不支持:Opera Android、Samsung Browser
Chrome 覆盖率已经很高,Firefox 156 是本周新增的主力。如果你的项目不需要覆盖 Opera Android 和旧版 Samsung Browser,生产可用。如果需要保守,可以用 @supports 渐进增强:
--brand: oklch(55% 0.22 270);
/* 降级:Safari/旧浏览器用直接写死的透明版本 */
.button-ghost {
background: oklch(55% 0.22 270 / 50%);
}
@supports (color: alpha(from red / 50%)) {
.button-ghost {
background: alpha(from var(--brand) / 50%);
}
}
实际用在哪里
悬停状态:卡片 hover 时背景淡化,而不是颜色变化
.card {
background: var(--brand);
transition: background 0.2s;
}
.card:hover {
background: alpha(from var(--brand) / 40%);
}
焦点环:focus 样式继承主题色的半透明版本
:focus-visible {
outline: 2px solid alpha(from var(--brand) / 60%);
}
遮罩层:叠加层用主色 20% 透明度,而不是写死 #ffffff33
.modal-overlay {
background: alpha(from var(--brand) / 20%);
}
下一步
- 查设计系统里哪些颜色变量缺少透明版本:如果你的 –brand 变量只有一个,而组件里到处写 oklch(数字 数字 数字 / 50%),现在可以统一收口
- Safari 27 稳定版预计年底到达:届时覆盖率将超过 90%,现在加 @supports 降级即可
- 对比 color-mix 的使用场景:记住 alpha() 是改透明度,color-mix 是混颜色,不要混用
评论区
0 条评论
登录后可评论。