Colores relativos

Crear variaciones de colores a partir de otros


—— ——

Quizás en alguna ocasión, te hayas planteado la opción de obtener variaciones de colores que estás utilizando. Algo así como una versión un poco más clara o más oscura de un color concreto, o tonalidades ligeramente más rojas, más verdes o más azules, por ejemplo. Esto es lo que se conoce como Colores relativos, ya que es una forma de establecer un color en relación a otro.

Colores relativos en CSS

En el CSS que conocíamos hasta ahora, hay formas de crear colores relativos, pero no son muy prácticas que digamos. Por ejemplo, mediante el uso de variables de CSS y funciones de color como rgb() podríamos realizar lo siguiente:

.item {
  --r: 75%;
  --g: 25%;
  --b: 100%;
  --alpha: 33%;

  width: 100px;
  height: 50px;
  background: rgb(var(--r) var(--g) var(--b) / var(--alpha));
}

Creamos tres variables --r, --g y --b, donde cada una guarda la cantidad de color de los canales RGB. Además, también guardamos el canal alfa (transparencia) en una variable --alpha. Finalmente, todo ello lo usamos en el interior de una función rgb() de sintaxis moderna.

Hasta aquí, nada raro, incluso podríamos crear unas clases alternativas que modifiquen el valor de las variables --r, --g y --b, o la variable --alpha, y tengamos una suerte de Tailwind, UnoCSS u otras librerías CSS basadas en la filosofía de clases de utilidad:

.alpha-66 { --alpha: 66%; }
.alpha-100 { --alpha: 100%; }
.blue-400 { --r: 25%; --g: 25%; --b: 75%; }
.green-400 { --r: 25%; --g: 75%; --b: 25%; }

Sin embargo, esto no es muy práctico y no puede utilizarse con esquemas de color como hexadecimal, por ejemplo. Quizás sería mejor tener un mecanismo más sencillo para realizar variaciones de colores.

Colores derivados con from

Mediante la palabra clave from, en el interior de una función de color rgb(), podemos establecer un color de origen para realizar una cierta modificación y crear un nuevo color relativo o derivado:

Estructura Descripción
rgb(from r g b) Modifica el color, variando sus componentes r, g y/o b.
rgb(from r g b / alpha) Idem, pero variando también el canal alpha (transparencia).
hsl(from h s l / alpha) Idem, pero utilizando la función de color hsl().
hwb(from h w b / alpha) Idem, pero utilizando la función de color hwb().
lab(from l a b / alpha) Idem, pero utilizando la función de color lab().
oklab(from l a b / alpha) Idem, pero utilizando la función de color oklab().
lch(from l c h / alpha) Idem, pero utilizando la función de color lch().
oklch(from l c h / alpha) Idem, pero utilizando la función de color oklch().

Como se puede ver en la tabla, no estamos limitados a usar siempre la función rgb(), a pesar de que los ejemplos sólo utilicemos dicha función. Eso sí, recuerda cambiar las iniciales de los canales.

En el siguiente fragmento de código CSS mostramos un ejemplo, donde utilizamos la palabra clave from para obtener el color #a8201a, una tonalidad concreta de rojo. El navegador, leerá dicho color y lo separa en los componentes r, g y b, de forma que luego podemos indicarlos literalmente:

.item {
  background: rgb(from #a8201a r g b);
}

En este caso, no estamos haciendo nada, ya que escribimos r g b literalmente, por lo que se crea una variación que es el mismo color original, pero por ejemplo, si anulamos el canal r (rojo) nos quedará un color similar a un gris oscuro tirando a verde:

.item {
  background: rgb(from #a8201a 0 g b);
}

En este caso estamos anulando el canal r con un 0, mientras que el canal g y b se mantiene igual. Esto crearía el color relativo #00201a desde el original #a8201a.

Recuerda que la palabra clave from sólo se puede utilizar con la sintaxis de color moderna. Mediante sintaxis legacy como rgb(r, g, b) o rgba(r, g, b, alpha) no funcionará.

Variaciones con calc()

Si lo deseamos, también podemos combinar el uso de from con la función calc() para calcular variantes de color. Por ejemplo, observa este nuevo fragmento de código. En él variamos nuevamente los colores:

.item-1 {
  background: rgb(from var(--color) calc(r - 20%) calc(g - 20%) calc(b - 20%));
}

.item-2 {
  background: rgb(from var(--color) calc(r + 20%) calc(g + 20%) calc(b + 20%));
}

En este caso, obtenemos desde una variable --color el color original, que a priori desconocemos. En el primer item, reducimos un 20% los canales rojo, verde y azul, mientras que en el segundo item, los aumentamos un 20%. Aunque desconocemos el color, sabemos que el primer item va a ser más oscuro, ya que #000000 es color negro y #ffffff es color blanco. Por lo tanto, reducir equivale a oscurecer y aumentar equivale a aclarar.

Variaciones del canal alpha

Aunque no es estrictamente obligatorio indicarlo, recuerda que la sintaxis de colores permite indicar un canal alpha para establecer la transparencia de nuestro color. En caso de omitirse, el canal alpha será 1 o 100%, es decir, totalmente opaco.

Observa el siguiente fragmento de código CSS:

.item {
  background: rgb(from #a8201a r g b / calc(alpha - 20%));
}

En este caso hemos indicado la palabra clave alpha para variar o modificar en base al canal alpha de nuestro color original. Hemos reducido el canal alpha un 20%, por lo que el color resultante será algo más transparente que el color original.

Cuidado, el soporte de esta característica aún está en fase experimental y no está disponible en todos los navegadores:

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev