Crea colores nuevos en función de los canales y valores de otro color.
En Chrome 119, es una función de color muy potente del nivel 5 de color de CSS. La sintaxis de color relativa crea una ruta de acceso fluida para la manipulación de colores dentro de CSS, lo que ofrece a los autores y diseñadores las siguientes posibilidades:
- Aclarar
- Oscurecer
- Saturate
- Desaturar
- Potenciador de croma
- Cómo ajustar la opacidad
- Invertir
- Complementos
- Conversión
- Contraste
- Paletas de colores
Antes de la sintaxis de color relativa, para modificar la opacidad de un color, debes crear propiedades personalizadas para los canales de un color, generalmente HSL, y ensamblarlas para crear un color final y un color final de la variante. Esto significa administrar muchas piezas de color, lo que puede volverse una carga rápidamente.
:root {
--brand-hue: 300deg;
--brand-saturation: 75%;
--brand-lightness: 50%;
--brand-hsl:
var(--brand-hue)
var(--brand-saturation)
var(--brand-lightness);
--brand-color: hsl(var(--brand-hsl));
/* all this work just so I can set the opacity to 50% in a variant */
--brand-color-variant: hsl(var(--brand-hsl) / 50%);
}
Después de la sintaxis de color relativa, puedes crear un color de marca con cualquier espacio de color o sintaxis que necesites y crear una variante de opacidad media con mucho menos código. También es mucho más fácil leer el propósito de los estilos y el sistema.
:root {
--brand-color: hsl(300deg 75% 50%);
--brand-color-variant: hsl(from var(--brand-color) h s l / 50%);
}
Esta publicación te ayudará a aprender la sintaxis y demostrar manipulaciones de colores comunes.
Si prefieres el video, este Desafío de GUI abarca casi todo el siguiente artículo.
Descripción general de la sintaxis
El objetivo de la sintaxis de color relativa es permitir derivar un color de otro. El color base se denomina color de origen, que es el color que aparece después de la nueva palabra clave from
. El navegador convertirá y dividirá este color de origen, y ofrecerá las partes como variables para usar en la nueva definición de color.
En el diagrama anterior, se muestra que el color de origen green
se convierte en el espacio de color del color nuevo y se convierte en números individuales representados como variables r
, g
, b
y alpha
, que luego se usan directamente como valores de un color rgb()
nuevo.
Si bien en esta imagen se muestra el desglose, el proceso y las variables, tampoco cambia el color. Las variables se vuelven a colocar en el color sin cambios, por lo que el color sigue siendo verde.
La palabra clave from
La primera parte de la sintaxis que debes aprender es la adición de from <color>
para especificar un color. Se coloca justo antes de especificar los valores. Este es un ejemplo de código en el que todo lo que se agregó es from green
, justo antes de que se especifiquen los valores de rgb()
.
.syntax-introduction_same-colors {
color: green;
color: rgb(0 128 0);
color: rgb(from green r g b); /* result = rgb(0 128 0) */
}
Esa palabra clave from
, cuando se ve como el primer parámetro en la notación funcional, convierte la definición de color en un color relativo. Después de la palabra clave from
, CSS espera un color, un color que inspirará el siguiente.
Conversión de color
En términos más simples, convierte el verde en canales de r, g y b para usarlos en un color nuevo.
rgb(from green r g b) /* r=0 g=128 b=0 */
rgb(from rgb(0 128 0) r g b); /* r=0 g=128 b=0 */
Colores de las propiedades personalizadas
La lectura de rgb from green
es muy clara y fácil de entender. Es por eso que las propiedades personalizadas y la sintaxis de color relativa son una combinación tan buena, ya que puedes quitar el misterio del color from
. Por lo general, tampoco es necesario que conozcas el formato de color del color de la propiedad personalizada, ya que crearás un color nuevo en el formato que elijas.
rgb(from rgb(255 105 180) r g b) /* ????? */
rgb(from var(--hotpink) r g b) /* clear */
Trabaja en tu espacio de color preferido
Puedes elegir el espacio de color con la notación de color funcional que elijas.
rgb(from hsl(120 100% 25%) r g b) /* r=0 g=128 b=0 */
hsl(from hsl(120 100% 25%) h s l) /* h=120 s=100% l=25% */
hwb(from hsl(120 100% 25%) h w b) /* h=120 w=0% b=50% */
lch(from hsl(120 100% 25%) l c h) /* l=46 c=68 h=134 */
La sintaxis de color relativa tiene ese paso de conversión. El color después de from
se convierte en el espacio de color como se especifica al comienzo del color relativo. La entrada y la salida no tienen que coincidir, lo que es muy liberador.
La capacidad de elegir un espacio de color también es útil, ya que tiende a enfocarse más en el tipo de alternancia de colores que en una preferencia. La preferencia está en los resultados, no en el formato de color ni en los tipos de canales. Esto se aclarará mucho más en las secciones en las que se muestran casos de uso, ya que los diferentes espacios de color se destacan en diferentes tareas.
Combina, haz coincidir, omite y repite las variables
Algo extraño pero emocionante de esta sintaxis es que las variables no se tienen que volver a ordenar y se pueden repetir.
rgb(from green g g g) /* rgb(128 128 128) */
rgb(from green b r g) /* rgb(0 0 128) */
rgb(from green 0 0 g) /* rgb(0 0 128) */
Opacidad como variable
La sintaxis también proporciona la opacidad como una variable llamada alpha
. Es opcional y va después de /
en la notación de color funcional.
rgb(from #00800080 r g b / alpha) /* alpha=50% */
rgb(from rgba(0,128,0,.5) r g b / alpha) /* alpha=50% */
rgb(from rgb(0 128 0 / 50%) r g b / alpha) /* alpha=50% */
Usa calc() o alguna otra función de CSS en las variables.
Hasta ahora, hemos estado creando el color verde una y otra vez. Aprender la sintaxis, familiarizarte con los pasos de conversión y desestructuración Ahora es el momento de modificar las variables y modificar el resultado para que no sea igual que la entrada.
green /* h=120 s=100% l=25% */
hsl(from green calc(h * 2) s l) /* h=240 s=100% l=25% */
Ahora es azul marino. Se duplicó el tono, se tomó un tono de 120
y se convirtió en 240
, lo que alteró por completo el color. Esto hizo girar el tono a lo largo de la rueda de color, un truco ingenioso que se simplifica mucho con los espacios de color cilíndricos, como HSL, HWB, LCH y OKLCH.
Para ver visualmente los valores de los canales, de modo que puedas obtener la matemática correcta sin adivinar ni tener que memorizar las especificaciones, prueba esta herramienta de valores de canales de sintaxis de color relativa. Revela el valor de cada canal según la sintaxis que especifiques, lo que te permite saber exactamente qué valores tienes disponibles para usar.
Cómo verificar la compatibilidad del navegador
@supports (color: rgb(from white r g b)) {
/* safe to use relative color syntax */
}
Casos de uso y demostraciones
Los siguientes ejemplos y casos de uso tienen muchas sintaxis alternativas para lograr resultados similares o los mismos. Las variaciones provienen de los espacios de color y los canales que ofrecen.
Además, muchos ejemplos mostrarán ajustes de color con el texto de by
y to
. Un by
de color cambiado es un cambio de color relativo, un cambio que usa el valor de la variable y realiza un ajuste en función de su valor actual. Un to
de color cambiado es un cambio de color absoluto, un cambio que no usa el valor de la variable y, en su lugar, especifica un valor completamente nuevo.
Puedes encontrar todas las demostraciones en esta colección de Codepen.
Aclarar un color
Los espacios de color OKLCH, OKLAB, XYZ o sRGB proporcionan los resultados más predecibles cuando se aclaran los colores.
Aclarar en una cantidad
En el siguiente ejemplo, .lighten-by-25
toma el color blue
y lo convierte en OKLCH. Luego, aclara el azul aumentando el canal l
(luminosidad) multiplicando el valor actual por 1.25
. Esto lleva la luminosidad azul a blanco en un 25%.
.lighten-by-25 {
background: oklch(from blue calc(l * 1.25) c h);
}
Aclarar a un valor específico
En el siguiente ejemplo de .lighten-to-75
, no se usa el canal l
para aclarar blue
, sino que se reemplaza por completo el valor por 75%
.
.lighten-to-75 {
background: oklch(from blue 75% c h);
}
Cómo oscurecer un color
Los mismos espacios de color que son eficaces para iluminar un color también son excelentes para oscurecer un color.
Oscurecer en una cantidad
En el siguiente ejemplo, .darken-by-25
toma el color azul y lo convierte en OKLCH. Luego, oscurece el azul disminuyendo el canal l
(luminosidad) en un 25% multiplicando el valor por .75
. Esto empuja el color azul hacia el negro en un 25%.
.darken-by-25 {
background: oklch(from blue calc(l * .75) c h);
}
Oscurecer hasta un valor especificado
En el siguiente ejemplo, .darken-to-25
no usa el canal l
para oscurecer blue
, sino que reemplaza por completo el valor con 25%
.
.darken-to-25 {
background: oklch(from blue 25% c h);
}
Satura un color
Saturación por un importe
En el siguiente ejemplo, .saturate-by-50
usa el s
de hsl()
para aumentar la intensidad de orchid
en un 50%
relativo.
.saturate-by-50 {
background: hsl(from orchid h calc(s * 1.5) l);
}
Saturación a una cantidad específica
En el siguiente ejemplo, .saturate-to-100
no usa el canal s
de hsl()
, sino que especifica un valor de saturación deseado. En este ejemplo, la saturación se aumenta a 100%
.
.saturate-to-100 {
background: hsl(from orchid h 100% l);
}
Desatura un color
Desaturar en una cantidad
En el siguiente ejemplo, .desaturate-by-half
usa el s
de hsl()
para disminuir la saturación de indigo
a la mitad.
.desaturate-by-half {
background: hsl(from indigo h calc(s / 2) l);
}
Desaturar a un valor específico
En lugar de desaturar en una cantidad, puedes desaturar hasta un valor específico deseado. En el siguiente ejemplo, .desaturate-to-25
crea un color nuevo basado en indigo
, pero establece la saturación en un 25%.
.desaturate-to-25 {
background: hsl(from indigo h 25% l);
}
Cómo aumentar el croma de un color
Este efecto es similar a saturar un color, pero es diferente en algunos aspectos. En primer lugar, es un cambio de chroma
y no de saturation
, y esto se debe a que los espacios de color que pueden aumentar al rango dinámico alto no usan saturación. Los espacios de color que incluyen chroma
son compatibles con el alto rango dinámico, lo que permite a los autores aumentar la intensidad del color más allá de lo que puede hacer la saturación.
.increase-chroma {
background: oklch(from orange l calc(c + .1) h);
}
Cómo ajustar la opacidad de un color
Hacer una variante semitransparente de un color es uno de los ajustes de color más comunes que se realizan en los sistemas de diseño. Si no lo viste, consulta el ejemplo en la introducción de este artículo, ya que describe muy bien el espacio del problema.
Ajusta la opacidad en una cantidad
.decrease-opacity-by-25 {
background: rgb(from lime r g b / calc(alpha / 2));
}
Ajusta la opacidad a un valor específico
.decrease-opacity-to-25 {
background: rgb(from lime r g b / 25%);
}
Invertir un color
La inversión de colores es una función de ajuste de colores común que se encuentra en las bibliotecas de colores. Una forma de lograr esto es convertir un color a RGB y, luego, restar el valor de cada canal de 1.
.invert-each-rgb-channel {
background: rgb(from yellow calc(255 - r) calc(255 - g) calc(255 - b));
}
Cómo complementar un color
Si tu objetivo no era invertir un color, sino complementarlo, es probable que lo que busques sea la rotación de matiz. Elige un espacio de color que ofrezca el tono como un ángulo y, luego, usa calc()
para rotar el tono en la cantidad que desees.
Para encontrar el complemento de un color, se rota media vuelta. En este caso, puedes agregar o quitar 180
del canal h
para obtener el resultado.
.complementary-color {
background: hsl(from blue calc(h + 180) s l);
}
Cómo contrastar un color
Como método para lograr relaciones de contraste de colores accesibles, considera L* (Lstar).
Se usa el canal de luminosidad (L) uniforme de manera aproximada (aproximadamente) del LCH y el OKLCH, en un calc()
. Según si te orientas a un contraste bajo, medio o alto, el delta de L· es de alrededor de ~40, ~50 o ~60.
Esta técnica funciona bien con cualquier tono en LCH u OKLCH.
Contrasta un color más oscuro
La clase .well-contrasting-darker-color
demuestra L* con un delta de 60.
Dado que el color de origen es oscuro (valor bajo de luminosidad), se agrega un 60% (0.6) al canal de luminosidad. Esta técnica se usa para encontrar un color de texto oscuro, del mismo tono y bien contrastado en un fondo claro.
.well-contrasting-darker-color {
background: darkred;
color: oklch(from darkred calc(l + .60) c h);
}
Contrasta un color más claro
La clase .well-contrasting-lighter-color
también muestra L* con un delta del 60%. Dado que el color de origen es un color claro (claridad de alto valor), se resta 0.60 del canal de luminosidad.
.well-contrasting-lighter-color {
background: lightpink;
color: oklch(from lightpink calc(l - .60) c h);
}
Paletas de colores
La sintaxis de color relativa es muy buena para crear paletas de colores. Es especialmente útil y potente debido a la cantidad de espacios de color disponibles. En los siguientes ejemplos, se usa OKLCH porque el canal de luminosidad es confiable y el canal de tono se puede rotar sin efectos secundarios. En el ejemplo final, se muestra una combinación de ajustes de luminosidad y rotación de tono para obtener un resultado más interesante.
Abre el código fuente de ejemplo para estas y cambia el --base-color
para ver cuán dinámicas son estas paletas. ¡Es divertido!
Si te gustan los videos, te daré información detallada sobre cómo crear paletas de colores en CSS con OKLCH en YouTube.
Paletas monocromáticas
Para crear una paleta monocromática, debes hacerlo con el mismo tono, pero con variaciones de luminosidad y oscuridad. El color del medio es el color de origen de la paleta, en el que se colocan dos variantes más claras y dos más oscuras a cada lado.
:root {
--base-color: deeppink;
--color-0: oklch(from var(--base-color) calc(l + .20) c h); /* lightest */
--color-1: oklch(from var(--base-color) calc(l + .10) c h);
--color-2: var(--base-color);
--color-3: oklch(from var(--base-color) calc(l - .10) c h);
--color-4: oklch(from var(--base-color) calc(l - .20) c h); /* darkest */
}
Prueba una gran cantidad de paletas creadas con sintaxis de color relativa y OKLCH
Open Props, una biblioteca de variables de CSS gratuitas, ofrece paletas de colores creadas con esta estrategia y las hace fáciles de usar con una importación. También se basan en un color que puedes personalizar. Solo debes asignarle un color y se generará una paleta.
Paletas análogas
Dado que la rotación de matiz es muy fácil con OKLCH y HSL, es muy sencillo crear una paleta de colores análogos. Rota el matiz según la cantidad que te guste para los resultados y cambia el color base, y observa cómo el navegador crea paletas nuevas.
:root {
--base-color: blue;
--primary: var(--base-color);
--secondary: oklch(from var(--base-color) l c calc(h - 45));
--tertiary: oklch(from var(--base-color) l c calc(h + 45));
}
Paletas tríadicas
Al igual que los colores complementarios, las paletas de colores triádicas son opuestas, pero armoniosas, según un color de base. Cuando un color complementario está en el lado opuesto de un color, como una línea recta dibujada en el medio del círculo cromático, las paletas triádicas son como un triángulo de líneas, en el que se encuentran 2 colores igualmente rotados a partir de un color base.
Para ello, rota el tono 120deg
.
Esta es una ligera simplificación de la teoría del color, pero es suficiente para comenzar a usar las paletas triádicas más complejas si te interesa.
:root {
--base-color: yellow;
--triad-1: oklch(from var(--base-color) l c calc(h - 120));
--triad-2: oklch(from var(--base-color) l c calc(h + 120));
}
Paletas tetradic
Las paletas tetrádicas son cuatro colores divididos de manera uniforme alrededor de la rueda de colores, lo que genera una paleta sin un valor dominante claro. También puedes pensar en ello como dos parejas de colores complementarios. Si se usa con prudencia, puede ser muy significativo.
Esta es una ligera simplificación de la teoría del color, pero es suficiente para comenzar a usar las paletas tetradic más complejas si te interesa.
:root {
--base-color: lime;
--color-1: var(--base-color);
--color-2: oklch(from var(--base-color) l c calc(h + 90));
--color-3: oklch(from var(--base-color) l c calc(h + 180));
--color-4: oklch(from var(--base-color) l c calc(h + 270));
}
Monocromático con una leve rotación de tono
Muchos expertos en color tienen este truco bajo la manga. El problema es que una escala de colores monocromática puede ser bastante aburrida. La solución es agregar una rotación de tono menor o mayor a cada color nuevo a medida que cambia la luminosidad.
En el siguiente ejemplo, se reduce la luminosidad en un 10% de cada muestra y también se rota el matiz 10 grados. El resultado es una paleta de rosa intensa a índigo que parece combinarse sin problemas como lo haría un gradiente.
:root {
--base-color: deeppink;
--color-1: var(--base-color);
--color-2: oklch(from var(--base-color) calc(l - .10) c calc(h - 10));
--color-3: oklch(from var(--base-color) calc(l - .20) c calc(h - 20));
--color-4: oklch(from var(--base-color) calc(l - .30) c calc(h - 30));
--color-5: oklch(from var(--base-color) calc(l - .40) c calc(h - 40));
}
Prueba esta tabla de clasificación creada con OKLCH y rotación de tono
La siguiente interfaz de tabla de clasificación usa esta estrategia de rotación de tono. Cada elemento de la lista hace un seguimiento de su índice en el documento como una variable llamada --i
. Luego, se usa para ajustar el croma, la luminosidad y el tono. El ajuste es solo de un 5% o 5 grados, mucho más sutil que el ejemplo anterior con el color rosa oscuro, por lo que se necesita un ojo agudo para notar el motivo por el que esta tabla de clasificación puede estar en cualquier tono con tanta elegancia.
Asegúrate de cambiar el tono en el control deslizante debajo de la tabla de clasificación y observa cómo la sintaxis de colores relativa crea hermosos momentos de color.
li {
--_bg: oklch(
/* decrease lightness as list grows */
calc(75% - (var(--i) * 5%))
/* decrease chroma as list grows */
calc(.2 - (var(--i) * .01))
/* lightly rotate the hue as the list grows */
calc(var(--hue) - (var(--i) + 5))
);
}