Cubo de color CSS-3

Espacios de colores CSS-3: RGB y HSL

Los colores CSS son valores que se aplican al color de fondo con la propiedad {background-color}, al color de bordes con {border-color}, o al color de primer plano con {color}. Entender como funcionan es básico para tener la suficiente agilidad en su uso. Los colores podemos analizarlos como una composición de tres dimensiones: rojo, verde y azul, red, gren, blue en inglés. Aunque hay más de una forma de componer un color, el espacio de colores RGB es el que se usa en CSS-2.1. Los valores son enteros entre 0 y 255, por lo que hay 2563 = 16.777.216 combinaciones de colores rojo, verde y azul.

CSS-3 HSL incorpora también el espacio de colores HSL, que son las iniciales de:

  • Hue: matiz, en el rango [0..360) grados
  • Saturation: saturación en el rango [0%..100%]
  • Lightness: luminosidad en el rango [0%..100%]

En este sistema el matiz de un color es una dimensión circular entre 0º y 360º, es decir un rango [0..360) sin llegar a tomar el valor de 360 pues equivale a cero. Por ejemplo, con cero grados tenemos el color rojo de tal forma que las otras dos variables saturación y luminosidad nos dan todas las tonalidades de ese color. El valor denominado normal de rojo, es decir, el que equivale en RGB a rgb(255,0,0), sería hsl(0,100%,50%) con una saturación del 100% y una luminosidad del 50%. Las fórmulas que permiten convertir entre valores RGB y HSL las incluyo dentro del módulo general-color.js con otras funciones de uso genérico para gestionar el color.

Podemos partir de estos conceptos básicos para crear un cubo de color RGB. No se trata de construir un verdadero cubo de 3 dimensiones, pues no es fácil representar algo de 3 dimensiones en una superficie de 2 dimensiones y poder acceder a los puntos interiores de ese objeto. Lo que haré es una especie de representación de ese cubo tomando 2 colores para el plano XY mientras que el tercero será el eje Z. La idea básica es construir una tabla para el plano XY donde cada celda será un color. Mientras que el eje Z para el tercer color lo pondremos aparte. Tendremos que limitar el número de colores, por ejemplo, a un cubo de 133 = 2.197 celdas. Así el cubo se estructura una tabla con 132 = 169 celdas del plano XY más las 13 de la guía del eje Z. Por cada valor de Z seleccionado tendremos 169 valores de color en el plano XY. Este cubo de dimensión 13 nos da 2.197 colores y cambiando la guías Z podemos tener 3 formas distintas de plasmar esos 2.197 colores.

En cuanto al espacio HSL lo que haré es crear una representación del círculo de matices con dos filas de colores. Con una dimensión N se crearán 2*(N-1) colores para la variable matiz, de tal forma que con dimensión 13 tendremos 24 ángulos separados 15º:

Ejemplo:

Las otras dos variables saturación y luminosidad se despliegan en el plano, la primera en el eje horizontal y la segunda en el vertical.

El cubo de color

Sin explicar más detalles veámos el cubo en funcionamiento. Tenemos a continuación un elemento <div> con un color de fondo que puede cambiarse con el cubo que está a continuación. Este cubo es un objeto de Javascript que se maneja en el módulo cubo-color.js y que puede vincularse con un objeto externo para modificar el color seleccionado.

Aplicación

Podemos cambiar las dimensiones del cubo con estos controles:

Dimensión (2 a 30):
En la nueva herramienta cubo de color he mejorado esta aplicación incluyendo un ajuste de color para acceder a todos los colores posibles. Además también se incluyen listas de color CSS con nombres y transparencias.

La selección de cada celda se muestra como color de fondo {background-color} en el elemento <div> externo que está antes del cubo de color. El texto es el string de ese color de fondo en el formato CSS. Para el color de ese texto, el llamado color de primer plano {color}, usamos el color resaltado con la función resaltarColor(red, green, blue, alfa) del módulo general-color.js para conseguir un contraste adecuado con el fondo.

Todos los cálculos internos del cubo de color se hacen en formato RGB incluso en el caso de HSL, pero el formato de presentación externo puede ser modificado a los señalados: RGB en sus modalidades 0-255, hexadecimal o porcentajes así como HSL. Hay que tener en cuenta que los navegadores aceptan HSL como valor para un estilo de color, pero no lo almacenan necesariamente como HSL. Por ejemplo, con este elemento:

<span style="color: hsl(0,100%,50%); 
border: blue solid 1px;" id="colorhsl"></span>    
    

Ejemplo:

Este ejemplo no funciona en IE8-9 pues no maneja HSL.

El color pasado en el estilo es hsl(0,100%,50%) para el rojo, de tal forma que el texto interior obtenido será rgb(255,0,0) (con los navegadores señalados más abajo), texto que hemos generado con el script de este documento en la carga del mismo extrayéndolo del estilo actual del elemento:

var spane = document.getElementById("colorhsl");
spane.innerHTML = "&nbsp;" + spane.style.color; 

Los navegadores actuales Firefox 6.0, Safari 5.0, Chrome 14.0 y Opera 11.51 harán una conversión de HSL a RGB y lo almacenarán con este formato. Por esta razón hacemos todo el proceso de cálculos internos del cubo de color con RGB, aunque luego ofrecemos las salidas en el formato seleccionado usando las fórmulas de conversión incluidas en el módulo general-color.js:

  • rgbToHex()
  • hexToRgb()
  • rgbToHsl()
  • hslToRgb()

Las conversiones a porcentajes no necesitan una fórmula específica, pues sólo hay que obtener el valor en RGB y hacer la operación 100*C/255 para C=[0..255].

Detalles del objeto cuboColor

Para poner el cubo de color de esta página necesitamos esto en la cabecera (el código de cada módulo CSS o JS puede consultarse con ver código fuente de Firefox por ejemplo):

...
<link rel="stylesheet" type="text/css" href="/res/sty/cubo-color.css" />    
<script type="text/javascript" src="/res/inc/general-color.js" charset="utf-8"></script>    
<script type="text/javascript" src="/res/inc/cubo-color.js" charset="utf-8"></script>    
<script>
//<![CDATA[
    var cubo = null;
    window.onload = function(){
        cubo = new cuboColor("cubo", "contiene-cubo", 
                Array("val-color: #color; background-color; innerText"), 13); 
        document.getElementById("dimension").value = cubo.dimension;
    }
    function actualizarDimension(){
        var elemento = document.getElementById("dimension");
        elemento.value =  cubo.validaDimension(elemento.value);
        cubo.creaCubo();
    }    
...

El cubo se crea al declarar la variable cubo = new cuboColor(). Pero también podemos volver a reconstruirlo con el método cubo.creaCubo(). El objeto cuboColor tiene el siguiente constructor:

new cuboColor(nombreInstancia, idDonde[[[[, queActualiza], tipoCubo], dimension], formatoValor])  
    

Los argumentos son estos:

  • nombreInstancia, un string obligatorio con el mismo nombre con el que se crea la variable.
  • idDonde, un string obligatorio que representa el atributo id de un elemento de bloque de la página donde vayamos a construir el cubo.
  • queActualiza, un array opcional para actualizar un elemento externo. Será como Array(string1, string2,...) donde cada elemento es un string como "idElemento: prop1; ...; propN", conteniendo dos partes separados por ":". A la izquierda está el ID del elemento que vamos a actualizar. A la derecha y separado por ";" están las propiedades de estilo que vamos a actualizar: "color", "background-color", "border-color", "value". Si queremos un color invertido anteponemos "#" a esa propiedad. Con "value" se actualiza el atributo value de un <input type="text"> cuando sea el elemento de este tipo o el texto interno para otros elementos.
  • tipoCubo, un string opcional con "rgb" (valor por defecto) o "hsl".
  • dimension, un entero opcional para la dimensión del cubo. Por defecto se crea de dimensión 13.
  • formatoValor, un string que será "rgb", "hex", "%", "hsl" para ofrecer el resultado en el formato adecuado para CSS. También hay otro valor "rgb-hidden" que ofrece el primer formato "rgb" pero ocultará los botones de selección inferiores. Hay que decir que el cubo trabaja internamente con el formato "rgb" y que sólo se hace una conversión cuando se presenta el texto en el elemento externo.