Sobre las funciones de color RGB, HSL, LCH y LAB

Poco a poco empiezan a oírse más comentarios sobre las nuevas funciones para declarar colores en CSS introducidos en el actual documento de trabajo (nivel 4) de la especificación del estándar de color. Y aunque todavía no es recomendación y el soporte de los navegadores es mínimo, parece que continuará adelante.

Como la especificación es muy amplia nos centraremos en entender el paso que se está dando y veremos cómo serán algunas de las nuevas funciones

El escenario actual

Estarás acostumbrado a declarar colores en CSS usando la notación hexadecimal, funciones rgb o hsl, o usando el nombre de un color.

O puede que uses alguna de las variantes que nos permite manipular la opacidad, lo cuál es en muchos casos muy necesario.

Pues bien, no importa cuál utilices ya que tu navegador usa por debajo rgb(). Puedes comprobarlo en la pestaña “computado” del inspector de elementos. Así que las diferencias entre cada una de ellas parece que son puramente azúcar sintáctico.

Captura del inspector web

Colores con nombre

Es la notación más sencilla porque su declaración es igual que el lenguaje humano. Y aunque es muy usada para ejemplos rápidos, es poco utilizada en el mundo real porque son colores predefinidos. Habría que memorizarlos y tener la suerte de que coincidan con la paleta de colores que tengamos en nuestro proyecto, lo cual será difícil a pesar de que el listado es bastante extenso. Bueno, por esto y porque hay ciertas inconsistencias que nos puede conducir a errores, como que darkgray es más claro que gray o lightpink más oscuro que pink.

RGB y RGBA

La función rgb() permite declarar un color descompuesto en las luces Rojo (red), Verde (green) y Azul (blue). Y el valor es el resultado de la suma de los tres haces de luz.

Por otro lado, en la función rgba() se añade el canal alpha para indicar la opacidad.

Cada uno de los argumentos de la función es un canal, y puede tomar un valor entre 0 y 255 (ambos incluidos) menos alpha, que será entre 0 y 1 (ambos también incluidos).

Aunque esta notación es muy popular, es difícil para nosotros como autores entender qué color será el resultante de la declaración.

.element {
	color: rgba(255, 0, 102, 1);
}

Hexadecimal

Permite escribir los valores separando el color en los mismos canales que rgb pero con una notación más sencilla. Así que aunque son iguales en su resultado, al ser más corta y más cómoda de escribir (sin comas ni paréntesis, luego hay menos posibilidad de cometer errores) la convierte en la más usada.

Su fórmula consiste en un ‘#’ seguido de 3, 4, 6, o 8 dígitos que pueden tomar valores entre 0 y 9 o caracteres entre A y F (sin diferenciar entre mayúsculas o minúsculas).

La notación de 3 dígitos es la abreviatura de la forma de 6 y se puede usar si se repite el mismo valor en cada par de dígitos.

Por otro lado, la notación de 4 dígitos es la abreviatura de la forma de 8, pero en este caso especificamos el canal alpha.

.element-A {
	color: #ff0066;
}

.another-element-A {
	color: #f06;
}

.element-B {
	color: #ff0066ff;
}

.another-element-B {
	color: #f06f;
}

HLS y HSLA

La función hsl es la más fácil de interpretar ya que cada canal no referencia a un color sino a un concepto sobre la percepción de la realidad: tinta (hue), saturación (saturation) y luminosidad (lightness).

La tinta es el color. Todos los colores posibles están dentro de una circunferencia y su valor se expresa en grados. 0 y 360 corresponden al rojo, 120 al verde y 240 al azul. Así que recordando estas 3 referencias es fácil aproximar el valor que quieras utilizar.

Rueda de color

La saturación es la viveza del color, su potencia. Y se expresa como porcentaje entre 0 y 100.

La luminosidad es la claridad. También se expresa como porcentaje entre 0 y 100. A mayor luminosidad más se acercará al blanco.

Y como en el caso de rgba(), la función hsla() usa el canal alpha para expresar una variación de su opacidad.

.element {
	color: hsl(336deg, 100%, 50%, 1);
}

Nada es más cómodo que copiar y pegar de Figma o Sketch, pero si nos tenemos que inventar un color, la notación hsl() es la más fácil para saber lo que elegimos y escapar de los colores predefinidos

sRGB y CIE LAB

Ahora bien. Todas las notaciones que usamos para declarar colores (no importa cuál) funcionan en el espacio de color sRGB. Un modelo que simplifica su representación en pantalla pero que arrastra incosistencias respecto a cómo en realidad las personas percibimos los colores. Esto se traduce en que los mismos niveles de saturación y luminosidad sobre tintas diferentes nos haga percibir algunos colores más luminosos que otros (como ocurre con el amarillo y el azul) pero en la naturaleza, si los niveles de saturación y luminosidad son iguales, no percibiríamos ninguno más vivo o luminoso que otro.

.element {
	color: hsl(53deg, 75%, 55%);
}

.another-element {
	color: hsl(228deg, 75%, 55%);
}

Es en este contexto en el que se introduce el espacio de color CIE LAB, que representa los colores de manera más fiel a nuestra percepción, y aparecen las nuevas funciones que usan este nuevo modelo.

LAB

El argumento “l” hace referencia a la luminosidad, pero es no como la L de hsl, sino CIE Lightness, y que se expresa como porcentaje entre 0 y 100.

Los argumentos “a” y “b” son valores positivos y negativos que oscilan entre -160 y 160, y hacen referencia a la distancia entre los ejes “a” y “b” en el espacio de color Lab.

El cuarto argumento está reservado para el canal alpha separado por el caracter slash (/), como en la función rgba() con la nueva notación.

.element {
	color: lab(54.25% 82.88 -18.86 / 1);
}

Quizá habréis notado en el inspector que en las funciones de color se separan los argumentos con espacios en lugar de comas, y al mismo tiempo el canal alpha con un slash. Esta es la nueva notación.

LCH

El argumento ‘l’ es como el de la función lab(), en cambio, el segundo y tercer parámetro son bastante diferentes.

El argumento ‘c’ es el croma o cantidad de color, y su valor oscila entre 0 y 230.

El argumento ‘h’ es la tinta y es similar a <hue> en la función hsl(). Puede tomar un valor entre 0 y 360 y aunque no tiene unidad, podemos entenderlo como una circuferencia que se completase en sentido anti-horario, es decir, los valores 0, 90, 270 y 360 se proyectarían sobre un eje de coordenadas cartesianas, siendo el valor 0 la parte positiva del eje ‘a’ (rojo púrpura), 90 el positivo del eje ‘b’ (amarillo mostaza), 180 el negativo de ‘a’ (cyan verdoso) y 270 el negativo de ‘b’ (azul cielo).

LCH

El cuarto argumento es reservado para el canal alpha, separado del resto de argumentos por un slash siguiendo la nueva notación.

.element {
	color: lch(54.25% 85 12.82 / 1);
}

Conclusiones

Probablemente empezaremos a utilizar estas nuevas funciones porque parece que mejoran las actuales, pero mejor no volvernos locos, si hemos llegado hasta el día de hoy sin grandes fuegos en la construcción de paletas de colores no habría que perder de repente la cabeza.

Hemos podido encontrarnos dificultades al usar generadores de paletas automáticos debido al defecto del modo sRGB, pero nada que no se puediese solucionar corrigiendo la saturación y luminosidad de algún color en concreto. Es decir, que si generamos nuestra paleta de forma aleatoria o si trabajamos en una aplicación para distribuir con diferentes temas (themes o skins), hay que evaluar con cuidado esos nuevos temas, ya que según qué tinta sea, este defecto puede levantar o hundir la interfaz, su contraste, y en consecuencia provocar problemas de accesibilidad.

Como decíamos al principio, la especificación es bastante más amplia y trae nuevas funciones como device-cmyk(), o color() entre otras, además, incorpora nuevos espacios de color predefinidos que podrán utilizarse, como display-p3 o rec2020 pero por el momento creo que lo recalcado es suficiente, y cuando el soporte sea mejor y podamos probar todo con comodidad, será momento de sacar más conclusiones.

Para saber más

comments powered by Disqus

Si te ha parecido interesante

Tanto si tienes alguna duda o quieres charlar sobre este tema, como si el contenido o nuestros perfiles te parecen interesantes y crees que pdemos hacer algo juntos, no dudes en ponerte en contacto con nosotros a través de twitter o en el email hola@mamutlove.com

Actualmente estamos abiertos a nuevas propuestas para colaborar