Volver a las notas

CSS alpha(): un color, todas sus transparencias

2 de noviembre de 2026·
csscolordesignsystemsbaseline
Demo en vivoAbrir a pantalla completa

CSS por fin tiene una función que hace una sola cosa: coger un color y cambiar su transparencia. alpha(from var(--brand) / 40%) es tu color de marca al 40 % de opacidad, esté escrito --brand en el formato que esté. Funciona en Chrome 152, Firefox 155 y Safari 27, y es Baseline desde el 14 de septiembre de 2026. En la demo de arriba, una sola variable alimenta una tarjeta de cristal, una barra de progreso, los bordes y una escala de seis pasos. Elige un color, mueve el deslizador y todo le sigue.

Por qué hacía falta una función propia

Si mantienes un sistema de diseño con tokens, conoces el problema. Defines --brand una vez y luego necesitas ese mismo color al 10 % para un fondo, al 30 % para un borde y al 50 % para un brillo. Durante años las opciones eran mantener un rgba() escrito a mano para cada uno (y olvidarte de actualizarlos cuando cambia la marca) o tirar de herramientas más pesadas:

  • La sintaxis de color relativo (rgb(from var(--brand) r g b / 40%)) funciona, pero tienes que elegir una función de color y escribir todos los canales. Con rgb(), hsl() o hwb() el resultado se serializa como color(srgb …), según MDN.
  • color-mix() con transparent (color-mix(in oklab, var(--brand) 40%, transparent)) también funciona, pero estás eligiendo un espacio de interpolación solo para que algo se vea a través.

alpha() te ahorra las dos decisiones. Según la especificación, parte de un color de origen y "solo cambia el canal alfa". Los componentes de color se quedan como están, y "el resultado de esta función está en el espacio de color del color de origen".

Cómo funciona

La gramática es corta. Esta es la línea de CSS Color Module Level 5:

alpha() = alpha(from <color> / [<alpha-value> | none])

Dos cosas que saber:

  1. Después de from va cualquier color: un hexadecimal, oklch(), un color con nombre o var(--brand).
  2. Después de la barra va el nuevo alfa. Dentro de él, la palabra clave alpha es el alfa actual del color de origen como número (1.0 equivale a 100 %), así que puedes trabajar en relativo.

Este es el patrón que usa la demo, sin la fontanería del deslizador:

:root {
  --brand: oklch(62% 0.24 300);
}

.glass {
  /* mismo color, opacidad fija */
  background: alpha(from var(--brand) / 16%);
  border: 1px solid alpha(from var(--brand) / 57%);
  box-shadow: 0 18px 50px -18px alpha(from var(--brand) / 47%);
}

.ghost {
  /* la mitad del alfa que ya tuviera el origen */
  background: alpha(from var(--brand) / calc(alpha * 0.5));
}

A diferencia de oklch(from …) o rgb(from …), alpha() no expone las palabras clave de los canales (l, c, h, r, g, b). MDN lo deja claro: solo se ocupa del canal alfa. Úsala cuando eso sea lo único que quieres cambiar, y deja la sintaxis de color relativo para cuando quieras una variante más clara o más saturada.

La diferencia del espacio de color, a la vista

El panel de abajo de la demo ejecuta getComputedStyle() sobre el mismo color escrito de tres formas. En Chromium 153, con oklch(62% 0.24 300) como origen y un 42 % de opacidad, obtengo:

alpha(from … / 42%)                     → oklch(0.62 0.24 300 / 0.42)
rgb(from … r g b / 42%)                 → color(srgb 0.626103 0.325981 0.99362 / 0.42)
color-mix(in oklab, … 42%, transparent) → oklab(0.62 0.12 -0.207846 / 0.42)

En pantalla, los tres se ven igual. Pero solo alpha() te devuelve lo que le diste: un color OKLCh sigue siendo OKLCh. Eso importa si inspeccionas tokens en DevTools o metes valores calculados en otras operaciones de color. Con un hexadecimal como origen, la misma llamada en Chromium devuelve rgba(255, 82, 0, 0.4), que sigue siendo el sRGB del que venía el hexadecimal.

Soporte en navegadores y trampas

  • Soporte: Chrome y Edge 152, Firefox 155, Safari 27 (escritorio e iOS), según browser-compat-data de MDN. Eso la convierte en Baseline "recién disponible" desde el 14 de septiembre de 2026, así que muchos navegadores que se usan hoy todavía no la entienden.
  • Plan B: el truco de siempre aquí no funciona. Lo normal es escribir antes una declaración de respaldo, y si el navegador no puede interpretar la segunda, la ignora. Pero alpha(from var(--brand) / 16%) contiene var(), así que el navegador no puede comprobarla hasta el momento del cálculo del valor. Si falla entonces, MDN explica que "la declaración no se ignora": la propiedad vuelve a su valor inicial o heredado. Probé el mismo patrón en Chromium con una función inventada: background: red; background: notafunction(from var(--brand) / 16%) acaba transparente, no rojo. Así que usa @supports. color-mix() es Baseline desde mayo de 2023, lo que lo convierte en un plan B seguro. Esto es lo que hace la demo:
.glass { background: alpha(from var(--brand) / 16%); }

@supports not (color: alpha(from red / 50%)) {
  .glass { background: color-mix(in oklab, var(--brand) 16%, transparent); }
}

La demo hace la misma comprobación en JavaScript con CSS.supports('color', 'alpha(from red / 50%)') y muestra un aviso cuando tira del plan B.

  • Los tokens se resuelven donde se declaran. Si escribes --brand-soft: alpha(from var(--brand) / 20%) en :root y luego redefines --brand dentro de .teal, var(--brand-soft) en esa sección sigue usando el color de la raíz. Lo comprobé en Chromium: el token se quedó naranja, mientras que el mismo alpha() escrito directamente en el elemento se volvió verde azulado. O declaras los tokens derivados en el elemento donde cambia --brand, o usas alpha() en línea.
  • Es from, no una coma. alpha(red, 50%) no es válido. Hacen falta tanto la palabra from como la barra.

Qué vigilar

  • El paso a "ampliamente disponible". Baseline "recién disponible" significa que todos los motores la han publicado, no que todos los usuarios hayan actualizado. Mantén el plan B un tiempo.
  • Que las herramientas de diseño se pongan al día. Los flujos de tokens y las apps de diseño que exportan una copia rgba() de cada tono podrían exportar un solo color más llamadas a alpha().
  • CSS Color 5 en conjunto. alpha() es nueva en el nivel 5, junto con la sintaxis de color relativo y color-mix(). Es la función más pequeña del conjunto, y seguramente la que más vas a escribir.

Fuentes