Interpolación de Color en CSS: Por Qué Gana OKLCH
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://colorfyi.com/iframe/entity//" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://colorfyi.com/entity//
Add a dynamic SVG badge to your README or docs.
[](https://colorfyi.com/entity//)
Use the native HTML custom element.
Cada vez que CSS mezcla dos colores — en un gradiente, en color-mix(), o en una transición — realiza interpolación de color: calculando valores intermedios entre un color inicial y uno final. Durante la mayor parte de la historia de la web, ese cálculo ocurría en el espacio de color sRGB, y los resultados eran a menudo turbios, desaturados o perceptualmente desiguales. Con CSS moderno, ahora puedes elegir el espacio de color para la interpolación. La elección importa enormemente, y OKLCH produce consistentemente los mejores resultados.
Este tutorial explica por qué la interpolación RGB falla, dónde se queda corta la interpolación HSL, y por qué OKLCH es el predeterminado correcto para gradientes y mezcla de colores en 2024 y más allá.
El Problema de la Interpolación RGB: Puntos Medios Turbios
Cuando escribes un gradiente CSS sin especificar un espacio de color, el navegador interpola en sRGB — calcula colores intermedios mezclando linealmente los valores de los canales R, G y B de forma independiente.
Esto parece razonable, pero falla gravemente cuando los dos extremos atraviesan el centro del cubo sRGB. Considera un gradiente de rojo a verde:
/* Predeterminado: interpola en sRGB */
background: linear-gradient(to right, #FF0000, #00FF00);
El punto medio de este gradiente en sRGB es #808000 — un oliva apagado. Matemáticamente, RGB 128, 128, 0 está exactamente a mitad de camino entre rojo y verde en valores de canal. Pero perceptualmente, no se parece en nada a un punto medio vibrante entre dos primarios vívidos. El gradiente se hunde a través de un valle oscuro y turbio antes de aclararse del otro lado.
El problema fundamental es que sRGB no es perceptualmente uniforme. Pasos numéricos iguales en R, G y B no corresponden a pasos iguales en color o brillo percibidos. El cubo sRGB fue diseñado para hardware de visualización, no para la visión humana.
/* Puedes forzar sRGB explícitamente */
background: linear-gradient(in srgb, red, blue);
/* O usar la sintaxis heredada (mismo resultado) */
background: linear-gradient(red, blue);
Ambos producen los mismos puntos medios desaturados. El problema es el espacio de color en sí, no la sintaxis.
El Problema de Gamma
Hay otra sutileza: los valores sRGB están codificados con gamma. Los valores sRGB brutos de 0.5 no corresponden al 50% de la luz física emitida por una pantalla. El punto medio perceptual real de un gradiente necesita calcularse en luz lineal, no en sRGB codificado con gamma. El nivel 4 de CSS introdujo in srgb-linear para abordar esto:
background: linear-gradient(in srgb-linear, red, blue);
El sRGB lineal es mejor que el sRGB gamma para transiciones de luminancia, pero aún no resuelve los problemas de desplazamiento de tono y caída de saturación porque sigue siendo un espacio RGB rectangular.
Desplazamientos de Tono en HSL
HSL fue introducido como una alternativa más legible para humanos que RGB. Su representación cilíndrica — Tono en un ángulo de 0 a 360°, Saturación y Luminosidad como porcentajes — facilita el razonamiento sobre las relaciones de color. Pero la interpolación HSL tiene su propio modo de fallo característico: los desplazamientos de tono.
Cuando interpolás entre dos colores HSL, el navegador recorre el arco más corto del círculo de tonos. Si vas de un rojo cálido (hsl(10, 100%, 50%)) a un azul frío (hsl(220, 100%, 50%)), el camino más corto pasa por morado y violeta — lo que puede o no ser lo que quieres.
Pero el problema más profundo es que la Luminosidad de HSL no es perceptualmente uniforme. Un amarillo en hsl(60, 100%, 50%) parece dramáticamente más brillante que un azul en hsl(240, 100%, 50%), aunque compartan el mismo valor L. Cuando interpolás de amarillo a azul en HSL, el brillo percibido sacude y se hunde de maneras que se sienten incoherentes.
/* Gradiente HSL — el brillo perceptual es desigual a través de los tonos */
background: linear-gradient(in hsl, hsl(60 100% 50%), hsl(240 100% 50%));
El punto medio de este gradiente en hsl(150, 100%, 50%) es un verde vívido que aparece perceptualmente más brillante que cualquiera de los extremos. El gradiente alcanza su pico en el medio en lugar de hacer una transición suave.
La interpolación HSL también tiene un problema de arco largo: el ángulo de tono se envuelve en 360°, y si interpolás de hsl(350, ...) (casi rojo) a hsl(20, ...) (naranja), HSL puede recorrer el largo camino alrededor del círculo de tonos a través de azul, verde y amarillo en lugar del camino corto a través del rojo.
OKLCH: Consistencia y Uniformidad Perceptual
OKLCH es una forma cilíndrica del espacio de color Oklab, diseñado por Björn Ottosson en 2020 específicamente para abordar las deficiencias de uniformidad perceptual de los espacios de color anteriores. Sus tres canales — L (luminosidad), C (croma) y H (ángulo de tono) — están calibrados para que cambios numéricos iguales en L produzcan cambios iguales en el brillo percibido, independientemente del tono.
Cuando interpolás entre dos colores OKLCH, obtienes:
- Brillo percibido consistente durante toda la transición — sin hundirse en puntos medios oscuros ni alcanzar picos brillantes abruptos.
- Croma preservado — los puntos medios permanecen vívidos porque el croma se interpola independientemente del tono.
- Caminos de tono más cortos e intuitivos — los ángulos de tono de OKLCH están distribuidos en orden perceptual, por lo que la interpolación pasa por los tonos intermedios esperados.
/* Gradiente OKLCH — vívido, perceptualmente uniforme */
background: linear-gradient(in oklch, red, blue);
Un gradiente de rojo a azul en OKLCH pasa por magenta y morado vívidos — los puntos medios perceptualmente intuitivos. Permanece saturado y uniformemente brillante en todo momento.
Comparación Lado a Lado
| Gradiente | Color del Punto Medio | Calidad Percibida |
|---|---|---|
in srgb de rojo a verde |
#808000 — oliva apagado | Turbio, valle oscuro |
in hsl de amarillo a azul |
Pico de verde vívido | Brillo desigual, pico de color |
in oklch de rojo a verde |
Amarillo cálido vívido | Suave, saturado, uniforme |
Para ver la diferencia por ti mismo, usa el Generador de Gradientes, que te permite previsualizar gradientes en diferentes espacios de color.
Cómo Convertir tus Colores a OKLCH
No necesitas reescribir cada valor de color en tu CSS. El indicador in oklch en un gradiente le dice al navegador que convierta los colores extremos a OKLCH antes de interpolar, luego convierta de vuelta al espacio de color de salida. Puedes mantener tus valores HEX:
/* Estos extremos HEX se convierten automáticamente a OKLCH para interpolación */
background: linear-gradient(in oklch, #FF5733, #3498DB);
#FF5733 es aproximadamente oklch(0.63 0.24 27) y #3498DB es aproximadamente oklch(0.63 0.14 232). Usa el Conversor de Color para comprobar los valores OKLCH de cualquier código HEX antes de diseñar un gradiente, para saber de antemano qué recorrerá la interpolación.
La Función color-mix()
La función CSS color-mix() es la API declarativa para mezclar dos colores, disponible en todos los navegadores modernos desde 2023. Su sintaxis incluye el espacio de color de interpolación como primer argumento:
color: color-mix(in oklch, #FF5733 50%, #3498DB);
Esto mezcla #FF5733 y #3498DB en proporciones iguales en el espacio OKLCH. El resultado es un intermedio vívido que parece un punto medio perceptual real entre los dos colores — no un promedio sRGB turbio.
Usos Prácticos de color-mix()
Crear variantes transparentes:
:root {
--brand: #2563EB;
--brand-10: color-mix(in oklch, var(--brand) 10%, transparent);
--brand-20: color-mix(in oklch, var(--brand) 20%, transparent);
--brand-50: color-mix(in oklch, var(--brand) 50%, transparent);
}
Teñir hacia blanco o negro:
:root {
--brand: #2563EB;
--brand-light: color-mix(in oklch, var(--brand) 70%, white);
--brand-dark: color-mix(in oklch, var(--brand) 70%, black);
}
Esto es la misma idea que un generador de tonos pero completamente en CSS, sin preprocesamiento. El resultado en el teñido OKLCH parece más natural que las operaciones equivalentes en HSL porque el croma cambia apropiadamente al acercarse al blanco o negro.
Derivación de estado hover:
.button {
background: var(--brand);
}
.button:hover {
background: color-mix(in oklch, var(--brand) 80%, black);
}
Advertencia: color-mix() en sRGB
Si omites el argumento in <espacio-de-color>, color-mix() usa la interpolación sRGB por defecto:
/* Esto usa sRGB — puede producir resultados turbios */
color: color-mix(#FF5733, #3498DB);
/* Correcto: especifica el espacio */
color: color-mix(in oklch, #FF5733, #3498DB);
Especifica siempre in oklch (u otro espacio preferido) explícitamente. El sRGB predeterminado se mantiene por compatibilidad con versiones anteriores, pero rara vez es la mejor elección.
Espacio de Color de Interpolación en Gradientes
La sintaxis CSS moderna te permite especificar el espacio de color de interpolación directamente en una declaración de gradiente usando in <espacio-de-color> después de la palabra clave de dirección:
/* sRGB (predeterminado, a menudo turbio) */
background: linear-gradient(to right, red, blue);
/* sRGB lineal (mejor luminancia, aún tiene problemas de tono) */
background: linear-gradient(in srgb-linear to right, red, blue);
/* HSL (desplazamientos de tono, brillo desigual) */
background: linear-gradient(in hsl to right, red, blue);
/* OKLCH (recomendado: vívido, perceptualmente uniforme) */
background: linear-gradient(in oklch to right, red, blue);
/* Oklab (también excelente, sintaxis menos intuitiva) */
background: linear-gradient(in oklab to right, red, blue);
Esta sintaxis se aplica a todos los tipos de gradiente: linear-gradient, radial-gradient y conic-gradient.
Dirección de Interpolación de Tono en OKLCH
Para la interpolación de tono específicamente, puedes controlar si el gradiente toma el arco más corto o más largo alrededor del círculo de tonos:
/* Arco más corto (predeterminado) */
background: linear-gradient(in oklch, hsl(30 100% 50%), hsl(270 100% 50%));
/* Arco más largo — recorre amarillo, verde, cyan, luego hasta morado */
background: linear-gradient(in oklch longer hue, hsl(30 100% 50%), hsl(270 100% 50%));
/* Arco creciente — siempre va en la dirección del aumento del ángulo de tono */
background: linear-gradient(in oklch increasing hue, hsl(30 100% 50%), hsl(270 100% 50%));
La palabra clave shorter hue (predeterminada) da el resultado más natural en la mayoría de los casos. La variante longer hue es útil para efectos de arcoíris o cuando específicamente quieres que el gradiente recorra una amplia porción del espectro de tonos.
Gradientes con Múltiples Paradas
La interpolación OKLCH se vuelve aún más valiosa para gradientes con múltiples paradas, porque cada segmento interpola a través de puntos medios perceptualmente vívidos:
/* Un gradiente arcoíris que permanece vívido en todo momento */
background: linear-gradient(
in oklch to right,
oklch(0.70 0.20 30), /* naranja-rojo */
oklch(0.80 0.20 90), /* amarillo */
oklch(0.75 0.20 150), /* verde */
oklch(0.65 0.20 240), /* azul */
oklch(0.60 0.20 300) /* morado */
);
Dado que los valores de L y C están calibrados perceptualmente, establecerlos en valores similares en todas las paradas da como resultado un arcoíris que parece naturalmente brillante y saturado, sin las caídas de luminancia comunes en los arcoíris sRGB.
Compatibilidad con Navegadores
La sintaxis in <espacio-de-color> para gradientes es compatible con todos los navegadores principales:
- Chrome/Edge: Compatibilidad completa desde la versión 111 (marzo de 2023)
- Firefox: Compatibilidad completa desde la versión 113 (mayo de 2023)
- Safari: Compatibilidad completa desde la versión 16.2 (diciembre de 2022)
Para navegadores más antiguos, usa la sintaxis heredada como alternativa:
/* Alternativa: gradiente sRGB */
background: linear-gradient(to right, #FF5733, #3498DB);
/* Moderno: interpolación OKLCH */
@supports (background: linear-gradient(in oklch, red, blue)) {
background: linear-gradient(in oklch to right, #FF5733, #3498DB);
}
Conclusiones Clave
- La interpolación sRGB (el predeterminado de CSS) produce puntos medios turbios y desaturados cuando los gradientes pasan cerca del centro del cubo sRGB — particularmente visible en gradientes de rojo a verde y de colores complementarios.
- La interpolación HSL evita algunos problemas RGB pero introduce brillo percibido inconsistente — su canal de Luminosidad no es perceptualmente uniforme — y puede producir caminos de tono inesperados.
- La interpolación OKLCH produce puntos medios vívidos y perceptualmente consistentes porque fue diseñada en torno a la visión humana. Los gradientes en OKLCH permanecen saturados y uniformemente brillantes en todo su rango.
- Usa
in oklchen cualquier gradiente:linear-gradient(in oklch to right, red, blue). Usacolor-mix(in oklch, color1 50%, color2)para mezcla programática. - El Conversor de Color te permite convertir valores HEX o RGB a OKLCH para entender cómo interpolarán tus colores antes de comprometerte con un diseño de gradiente.
- El Generador de Gradientes te permite previsualizar cómo diferentes espacios de color afectan la salida del gradiente para cualquier par de colores.
- La dirección de interpolación de tono puede controlarse con las palabras clave
shorter hue,longer hue,increasing hueydecreasing hue— útiles para efectos de arcoíris y control preciso de gradientes con múltiples paradas.