Si alguna vez has abierto un archivo de diseño, has copiado #3B82F6 y te has preguntado por qué ese mismo azul aparece también como rgb(59, 130, 246) y hsl(217, 91%, 60%), te has topado con los tres formatos de color que todo diseñador web y desarrollador front-end acaba teniendo que dominar. Los tres describen exactamente el mismo píxel. Lo que pasa es que lo describen en idiomas distintos, y cada idioma es bueno para una tarea diferente.
He sacado adelante sistemas de diseño en los que elegir el formato equivocado costó horas. Dale a un desarrollador un muro de códigos hexadecimales para el estado hover de un botón y obtendrás adivinanzas. Dale una escala HSL y la relación entre los colores resulta evidente. Así que esto es menos un árido volcado de especificaciones y más el modelo mental de trabajo que ojalá alguien me hubiera dado pronto: qué codifica realmente cada formato y cuándo recurrir a él.
HEX: el formato que copias, no en el que razonas
Un código de color hexadecimal no es más que RGB con otro disfraz. #RRGGBB son seis dígitos hexadecimales divididos en tres pares —rojo, verde, azul— y cada par es un byte. El hexadecimal (base 16) va de 0 a 9 y luego de A a F, así que dos dígitos hexadecimales cubren de 00 a FF, es decir, de 0 a 255 en decimal. Eso es exactamente un canal de 8 bits por color. Tres canales, tres bytes y los familiares 16.777.216 colores posibles (256 × 256 × 256).
Esa es toda la razón por la que son seis dígitos: un byte para cada R, G y B. Toma #3B82F6. Divídelo: 3B, 82, F6. Convierte cada par de hexadecimal a decimal —3B es 59, 82 es 130, F6 es 246— y acabas de hacer manualmente una conversión de hex a RGB. Es rgb(59, 130, 246). El mismo color, sin magia.
Existe una forma abreviada: #RGB se expande duplicando cada dígito, así que #F00 se convierte en #FF0000 (rojo puro) y #0AF en #00AAFF. Solo funciona cuando cada canal resulta ser un dígito repetido, por lo que sueles verla únicamente en valores redondos como #FFF, #000 o #333. Práctica en CSS escrito a mano, inútil para los azules arbitrarios que una marca usa de verdad.
El hexadecimal también maneja la transparencia, lo que sorprende a mucha gente. El CSS Color Module Level 4 añadió el hexadecimal de ocho dígitos, #RRGGBBAA, donde el último par es el alfa: 00 totalmente transparente, FF totalmente opaco. Así que #3B82F680 es ese mismo azul a aproximadamente un 50 % de opacidad. También hay una forma abreviada de cuatro dígitos (#RGBA), donde se aplican las reglas estilo #3B8 y cada dígito se duplica. Está soportado en todos los navegadores principales actuales; solo el viejísimo Internet Explorer se queda fuera, en cuyo caso rgba() es la alternativa.
La fuerza del hexadecimal es que es compacto e inequívoco: un solo token, fácil de copiar, fácil de pegar en una herramienta de diseño o en una variable CSS. Su debilidad es que no le dice casi nada a tu cerebro. ¿Es #3B82F6 más claro o más oscuro que #2563EB? Sinceramente, no puedes saberlo leyéndolos. Ahí es donde el hexadecimal se cae por el precipicio.
RGB: cómo piensa de verdad la pantalla
RGB es el modelo de color aditivo con el que funciona tu monitor. Cada píxel son tres lucecitas —roja, verde y azul— y los valores indican el brillo de cada luz, de 0 a 255. Las tres a 0 es negro (todas las luces apagadas). Las tres a 255 es blanco (todas las luces a tope). Sube el rojo y el verde, deja el azul apagado y obtienes amarillo, lo que resulta del revés si creciste mezclando pintura, donde el rojo y el verde dan un barro. Las pantallas suman luz; la pintura la resta. Esa es la idea central del color aditivo, y conviene retenerla porque explica muchos momentos de "¿por qué hace eso este color?".
En CSS escribes rgb(59 130 246) (sintaxis moderna con espacios) o rgb(59, 130, 246) (sintaxis heredada con comas); ambas valen. Añade el alfa con una barra —rgb(59 130 246 / 50%)— que ha reemplazado discretamente a la antigua función rgba(), aunque rgba() sigue funcionando en todas partes.
RGB es más legible que el hexadecimal porque los números son decimales y los canales son explícitos. Si ves rgb(250, 250, 250) sabes de inmediato que es un casi blanco, porque los tres están fijados muy altos. Pero comparte el verdadero defecto del hexadecimal: es pésimo para ajustar un color. Para oscurecer un 10 % rgb(59, 130, 246) no basta con tocar un número: tienes que mover los tres canales al unísono, y acertar las proporciones a mano es una causa perdida. Lo que nos lleva al formato que sí resuelve esto.
HSL: en el que sí deberías razonar
HSL —tono, saturación, luminosidad (en inglés hue, saturation, lightness)— es el formato en el que hago casi todo mi razonamiento, y es el que el generador de paletas de color muestra para cada color que produce, junto al RGB. En lugar de describir un color por cuánta de las tres luces hay que mezclar, lo describe como lo haría un ser humano.
- El tono (hue) es un ángulo en la rueda de color, de 0 a 360 grados. 0 (y 360) es rojo, 120 es verde, 240 es azul. Gira el ángulo y recorres el arcoíris.
- La saturación es lo intenso que es el color, de 0 % a 100 %. Al 0 % obtienes gris sea cual sea el tono; al 100 % es tan intenso como la pantalla permite.
- La luminosidad es lo claro u oscuro que es, de 0 % a 100 %. El 0 % es siempre negro, el 100 % siempre blanco, y el 50 % es la versión "pura" del tono.
Nuestro azul es hsl(217, 91%, 60%). Ahora fíjate en lo que HSL vuelve trivial. ¿Quieres una sombra más oscura para el estado de botón pulsado? Baja la luminosidad: hsl(217, 91%, 45%). ¿Un tinte más claro para un fondo en hover? Súbela: hsl(217, 91%, 92%). ¿Una versión más apagada y polvorienta para un control deshabilitado? Baja la saturación: hsl(217, 40%, 60%). El tono nunca se ha movido, así que se lee inequívocamente como la misma familia de azul en todo momento. Intenta hacer cualquiera de esas cosas editando canales RGB y entenderás por qué existe HSL.
Esto también explica por qué HSL es el lenguaje natural para construir escalas y tintes y sombras. Fija el tono, recorre la luminosidad en pasos —95 %, 85 %, 70 %, 55 %, 40 %, 25 %— y tendrás una rampa coherente desde un tinte de fondo pálido hasta un color de texto profundo, todos demostrablemente relacionados. Esa es la columna vertebral de cómo construyo tokens de color escalables para un sistema de diseño, y es el mecanismo que hay detrás de los tintes, sombras y matices. HSL incluso convierte la armonía de color en aritmética: un color complementario no es más que tu tono más 180 grados, y una tríada son tres tonos separados 120 grados. Si quieres la versión más a fondo de eso, entender la armonía de color en diseño UI lo explica paso a paso.
La sintaxis de CSS sigue el mismo patrón: hsl(217 91% 60%) o la heredada hsl(217, 91%, 60%), con alfa mediante hsl(217 91% 60% / 50%). El tono puede llevar una unidad deg, pero no la necesita. Una salvedad honesta: la luminosidad de HSL no es lo mismo que el brillo percibido. Un amarillo totalmente saturado al 50 % de luminosidad le parece a tu ojo mucho más brillante que un azul a esa misma luminosidad del 50 %. Eso es una limitación del modelo, no un fallo de tus ojos, y es justamente por lo que existe un verificador de contraste en vez de fiarse del número L: más sobre esto más abajo.
Entonces, ¿cuál usas en la práctica?
En la práctica usas los tres, por razones distintas, y el truco está en hacer coincidir el formato con el momento.
- HEX para almacenar y compartir un único color: guías de marca, una variable CSS, pasarle un valor a un compañero. Es la lengua franca; todo lo lee.
- RGB cuando trabajas canal por canal o te conectas con código que espera canales numéricos: canvas, procesamiento de imágenes o cualquier momento en que necesites valores en crudo de 0 a 255. También cuando quieres un alfa directo y prefieres no pensar en pares hexadecimales.
- HSL en cuanto necesites modificar o relacionar colores: construir estados hover y activos, generar una escala de tintes, encontrar un acento armonioso o afinar una paleta para modo oscuro donde no paras de ajustar la luminosidad y de bajar la saturación para que los colores no vibren sobre un fondo oscuro.
Mi flujo de trabajo real: razono y exploro en HSL y luego entrego los valores finales como variables hexadecimales. Elijo el tono, encuentro la rampa de luminosidad, compruebo la viveza con la saturación, y después congelo cada paso como un token hexadecimal que el resto del equipo consume.
De lo que ningún formato te libra es del contraste. Ni HEX, ni RGB, ni HSL te dicen si un texto será legible sobre un fondo; eso requiere un cálculo real de luminancia frente a las proporciones de la WCAG. La guía oficial de contraste del W3C exige al menos 4.5:1 para el texto de cuerpo normal. Por eso el generador acompaña sus lecturas de HSL y RGB con un verificador de contraste integrado: así puedes mover el control deslizante de luminosidad y ver cómo se actualiza la proporción en vivo, en lugar de publicar un azul bonito que nadie puede leer.
Una vez que estos tres formatos dejan de parecer cadenas crípticas y empiezan a parecer tres vistas de un mismo color —un token copiable, las luces en crudo de la pantalla y un conjunto de mandos pensados para humanos— dejas de pelearte con tus colores y empiezas a dirigirlos. Abre el generador de paletas de color, genera algo y observa cómo se mueven los números de HSL al ajustar una muestra. Esa retroalimentación en vivo es la forma más rápida de que todo esto te encaje.
Preguntas frecuentes
¿Qué es un código de color hexadecimal, dicho en pocas palabras?
Un código de color hexadecimal es un código de seis dígitos como #3B82F6 que almacena un color en tres bytes: uno para el rojo, otro para el verde y otro para el azul. Cada par de dígitos es un número hexadecimal de 00 a FF, es decir, de 0 a 255 en decimal. Así que #3B82F6 no es más que rgb(59, 130, 246) escrito de forma más compacta. Un octavo y séptimo dígito opcionales (#RRGGBBAA) añaden un canal alfa para la transparencia.
¿Cómo convierto un código hexadecimal a RGB a mano?
Divide los seis dígitos en tres pares y convierte cada par de hexadecimal a decimal. Para #3B82F6: 3B es 59, 82 es 130 y F6 es 246, lo que da rgb(59, 130, 246). El truco para un solo dígito es que A=10, B=11, hasta F=15, y el primer dígito se multiplica por 16. Cualquier herramienta de color —incluido el generador de paletas— hace esto al instante y muestra el RGB junto a cada color.
RGB vs HSL: ¿cuál debería usar?
Usa RGB (o hex) para almacenar y compartir un color fijo, ya que se corresponden directamente con la forma en que una pantalla mezcla la luz. Usa HSL siempre que necesites ajustar o relacionar colores: oscurecer una sombra, construir una escala de tintes o encontrar un acento armonioso. HSL separa el tono, la saturación y la luminosidad en mandos independientes, de modo que puedes oscurecer un color bajando un solo número en lugar de hacer malabares con tres canales RGB.
¿Por qué HSL es mejor para tintes y sombras?
Porque la luminosidad es un valor independiente en sí mismo. Fija el tono y la saturación, y luego sube la luminosidad para los tintes (más claros) y bájala para las sombras (más oscuras): cada paso pertenece de forma demostrable a la misma familia de color. Hacer lo mismo en RGB implica mover los tres canales en la proporción correcta, lo cual es impracticable a mano. Por eso HSL es el lenguaje natural de las escalas de color y de los tokens de los sistemas de diseño.
¿Pueden los códigos hexadecimales incluir transparencia?
Sí. El hexadecimal de ocho dígitos (#RRGGBBAA) añade un canal alfa como par final, donde 00 es totalmente transparente y FF es totalmente opaco, así que #3B82F680 es ese azul a alrededor del 50 % de opacidad. También existe una forma abreviada de cuatro dígitos (#RGBA). Funciona en todos los navegadores principales actuales; para entornos muy antiguos como Internet Explorer, usa rgba() como alternativa.
¿Quieres experimentar con los colores?
Prueba nuestro generador gratuito de paletas de color para encontrar tu armonía perfecta, con un comprobador de contraste WCAG integrado.
Abrir el generador