HEX vs RGB vs HSL para CSS y design tokens
Cuándo almacenar hex, rgb() o hsl() en design systems, cómo interactúan alpha y redondeo, y cómo encaja el contraste WCAG en el pipeline.
El mismo azul de marca llega como #2563EB, rgb(37, 99, 235) y hsl(221, 83%, 53%). Los tres pueden ser correctos, y los tres pueden divergir tras redondeo, composición alpha o un ajuste del diseñador en Figma.
Esta comparación ayuda a ingenieros de frontend y design systems a elegir un formato canónico de almacenamiento y derivar los demás sin romper comprobaciones de contraste.
Qué optimiza cada formato
| Formato | Fortaleza | Debilidad |
|---|---|---|
| HEX | Compacto en tokens, diffs y handoffs | Difícil aclarar/oscurecer mentalmente |
| RGB | Coincide con hojas de spec de diseño (0–255) | Verboso; relaciones de matiz opacas |
| HSL | Ajustes de tema (mismo hue, nueva lightness) | No es perceptualmente uniforme; sorpresas de contraste |
Ninguno de los tres es "más preciso": son vistas del mismo triple sRGB salvo que pases a espacios más amplios como OKLCH.
Elige una fuente de verdad por token
Los design systems sanos almacenan un valor autoritativo por token semántico (--color-primary) y generan salidas por plataforma:
:root {
--color-primary: #2563eb;
--color-primary-hover: #1d4ed8;
--color-on-primary: #ffffff;
}
Los componentes referencian --color-on-primary, no hex literales dispersos. Cuando marketing envía un swatch actualizado, actualiza el token una vez y reconstruye HSL/RGB derivados para docs.
Usa el Color Converter para verificar conversiones y contraste WCAG en pares de texto, no solo el swatch sobre blanco.
La composición alpha cambia el contraste
rgba(37, 99, 235, 0.12) sobre una tarjeta blanca no es el mismo par que texto #2563EB sobre azul sólido. Las comprobaciones WCAG deben usar foreground/background compuestos en la superficie que el usuario ve de verdad.
Superposiciones semitransparentes sobre fotos fallan más a menudo que rellenos planos: prueba el peor fondo, no el artboard por defecto de Figma.
HSL para paletas programáticas, hex para entrega
Un pipeline habitual:
- Los diseñadores crean en Figma (a menudo hex o RGB)
- Los ingenieros almacenan hex en tokens
- Scripts de build emiten HSL para generadores de tema o APIs de charts
- Exportaciones email/PDF reciben hex inline porque el soporte de
hsl()es inconsistente
Si generas estados hover restando lightness HSL, vuelve a ejecutar contraste en el nuevo par: "10% más oscuro" no garantiza AA.
Redondeo y deriva en ida y vuelta
HEX → HSL → HEX puede no devolver bytes idénticos. Eso importa cuando:
- Comparas snapshots CI de bundles CSS
- Sincronizas colores XML de Android con tokens web
Documenta reglas de redondeo en el README del repo de tokens. No dejes que cada app redondee por su cuenta.
Guía rápida de decisión
- ¿Necesitas diffs git compactos y soporte universal de herramientas? → Hex canónico
- ¿Integras canvas/WebGL/chart APIs? → Deriva RGB en build time
- ¿Construyes temas claro/oscuro desde una rampa de hue? → Autor ajustes en HSL u OKLCH, verifica contraste tras cada paso
- ¿Envías HTML email? → Solo hex en plantillas
Aprendizaje relacionado
Para ratios WCAG, sintaxis CSS Color Level 4 y un flujo de muestreo, consulta el curso Color for Developers.
Idea clave
HEX, RGB y HSL son vistas intercambiables, no religiones en competencia. Elige una forma canónica, deriva el resto de forma deliberada y mide contraste sobre fondos reales. Así #2563EB sigue siendo un solo azul en producción en lugar de cinco.