你以为调透明度只能靠 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)); }

三行核心差异:

  1. 不需要写 l、c、h:颜色通道保持原样,只碰 alpha
  2. 保留原始色彩空间:brand 是 oklch,结果也是 oklch,不会被强制转 sRGB
  3. 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%);
}

下一步

  1. 查设计系统里哪些颜色变量缺少透明版本:如果你的 –brand 变量只有一个,而组件里到处写 oklch(数字 数字 数字 / 50%),现在可以统一收口
  2. Safari 27 稳定版预计年底到达:届时覆盖率将超过 90%,现在加 @supports 降级即可
  3. 对比 color-mix 的使用场景:记住 alpha() 是改透明度,color-mix 是混颜色,不要混用

评论区

0 条评论

登录后可评论。