Saltar al contenido
AldeaCode Logo
Convertidor de Color / Tailwind Desarrollador 100% local

Convertidor de color para Tailwind CSS: OKLCH, @theme y escalas de tono

Tailwind v4 movió su sistema de color a OKLCH y la directiva @theme en CSS sustituyó casi toda la config en JS. Mapear un hex de marca a una paleta Tailwind es un ejercicio distinto al de v3, y la forma de la respuesta cambió con ello.

Tailwind v4 habla OKLCH

Desde la v4 la paleta por defecto de Tailwind se define en OKLCH en lugar de hex o RGB. El motivo es la uniformidad perceptual. Un azul en lightness 0.5 se ve igual de claro que un rojo en lightness 0.5, cosa que no pasa en HSL ni en sRGB. La escala de tonos (50, 100, 200 ... 950) tiene saltos de contraste consistentes en cualquier hue.

Efecto práctico: los colores se ven más parejos al intercambiarlos, las variantes de dark mode necesitan menos retoque manual, y el checker de contraste deja de quejarse a saltos aleatorios en la escala. Coste: los valores OKLCH no se parecen a nada legible a ojo, no puedes adivinar un color mirando oklch(0.65 0.18 250) como sí puedes con #3a86ff.

Mapear un hex de marca a Tailwind v4 significa pasarlo a OKLCH, elegir el tono más cercano de la escala existente, y o usar ese tono tal cual o generar una rampa custom 50..950 en torno a él.

De un único hex de marca a la rampa entera

El enfoque ingenuo es elegir cinco niveles de lightness (90, 75, 60, 45, 30) al mismo chroma y hue y llamarles 100, 300, 500, 700, 900. Vale como primera pasada y se rompe en los extremos, el chroma tiene que bajar cerca del blanco puro y del negro puro o el color sale neón en el extremo claro y barroso en el oscuro.

Receta mejor: parte del hex de marca, pásalo a OKLCH, coge el chroma como pico. Construye la rampa fijando el hue, bajando el chroma hacia los extremos (algo tipo chroma * sin(pi * lightness) si quieres una curva), y subiendo la lightness desde 0.97 (50) hasta 0.20 (950). La paleta propia de Tailwind usa una curva parecida.

Para la mayoría de proyectos no hace falta hacerlo a mano. Las herramientas (el conversor de este sitio, más generadores de rampas pensados para Tailwind) cogen un hex y escupen los once stops OKLCH. Los pegas en tu bloque @theme y tienes una paleta custom que cuadra con el resto del framework.

La sintaxis @theme inline

En la v4 el sitio canónico para los design tokens es @theme dentro de tu CSS. La sintaxis declara custom properties CSS bajo namespaces específicos de Tailwind, y el framework las recoge automáticamente.

Para un color el namespace es --color--. Defines once y tienes una paleta con el nombre que elegiste, con las utilidades estándar 50..950 (bg-brand-500, text-brand-900, etc.) generadas solas.

La config legacy en JS sigue funcionando para migración pero va camino de deprecación. Los proyectos nuevos en v4 entregan un único archivo CSS con @import "tailwindcss"; y un bloque @theme debajo, y el archivo JS desaparece entero. El bloque de abajo es una rampa de marca completa lista para pegar en app.css o globals.css.

Aliases semánticos y dark mode

Con la rampa puesta, dos convenciones más cierran el sistema. La primera son los aliases semánticos: --color-primary apunta a var(--color-brand-500) (o 600 si quieres un default más oscuro), --color-primary-hover apunta a 600 o 700, y tu código de componentes usa bg-primary en vez de bg-brand-500. Cambiar nombre o marca es entonces una sola línea.

La segunda es dark mode. El enfoque ingenuo es invertir cada tono con su espejo (50 toma el valor de 950, 950 el de 50). Funciona pero produce colores apagados en el extremo claro. El patrón limpio es dejar la rampa intacta y voltear solo los aliases semánticos: --color-primary apunta al 500 en light y al 400 en dark, porque OKLCH 400 sobre fondo oscuro tiene el mismo contraste percibido que 500 sobre fondo claro. El resultado es peso visual consistente en ambos modos sin doblar el número de tokens.

Ejemplo completo

css
/* app.css para Tailwind v4 */
@import "tailwindcss";

@theme {
  /* Rampa de marca generada desde #3a86ff (h=255, c=0.18) */
  --color-brand-50:  oklch(0.97 0.02 255);
  --color-brand-100: oklch(0.94 0.04 255);
  --color-brand-200: oklch(0.88 0.08 255);
  --color-brand-300: oklch(0.81 0.12 255);
  --color-brand-400: oklch(0.72 0.16 255);
  --color-brand-500: oklch(0.62 0.18 255);  /* el color de marca */
  --color-brand-600: oklch(0.54 0.17 255);
  --color-brand-700: oklch(0.46 0.15 255);
  --color-brand-800: oklch(0.38 0.12 255);
  --color-brand-900: oklch(0.30 0.09 255);
  --color-brand-950: oklch(0.22 0.06 255);

  /* Aliases semánticos, volteados por esquema */
  --color-primary:       var(--color-brand-500);
  --color-primary-hover: var(--color-brand-600);
  --color-primary-text:  var(--color-brand-50);
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-primary:       var(--color-brand-400);
    --color-primary-hover: var(--color-brand-300);
    --color-primary-text:  var(--color-brand-950);
  }
}

/* Uso en el markup:
   <button class="bg-primary text-primary-text hover:bg-primary-hover">
     Iniciar sesión
   </button>
*/

¿Solo necesitas el resultado?

Pega tu hex de marca en el convertidor de color en aldeacode.com y la forma OKLCH sale junto con la rampa de once tonos. Copia el bloque @theme directo a tu app.css, la paleta cuadra con el resto de Tailwind v4 por construcción y el dark mode es un giro de alias.

Abrir Convertidor de Color (Hex / RGB / HSL) →

Preguntas frecuentes

¿Sigue haciendo falta tailwind.config.js en v4?

Solo para plugins, rutas de contenido que el autodetect no pille, u overrides de tema que salen más fáciles en JS. Colores, fuentes, spacing y breakpoints viven en @theme dentro de CSS. Los proyectos nuevos en v4 a menudo no tienen archivo de config JS.

¿Por qué OKLCH y no LCH o HSL?

OKLCH usa el modelo perceptual OKLab, que corrige los problemas que tenía LCH CIE con el azul. El soporte en navegadores es universal desde 2023 (Safari 15.4 fue el último). HSL sigue soportado pero no es perceptualmente uniforme, la escala de tonos queda menos consistente entre hues.

¿Puedo seguir usando mi paleta hex actual en v4?

Sí. @theme acepta hex, rgb(), hsl(), oklch() o cualquier otra función de color CSS. La paleta funcionará, solo pierdes la uniformidad perceptual que la paleta por defecto de Tailwind saca de OKLCH. Mezclar es válido para una migración.