Usa OKLCH cuando sus coordenadas correspondan a la tarea
OKLCH es la forma polar de Oklab. L representa luminosidad perceptiva, C es chroma y H es un ángulo de tono. CSS Color 4 describe Oklab como optimizado para colores visualmente similares y señala mejoras de linealidad de tono, uniformidad perceptiva y predicción de chroma frente a CIE LCH. Esto hace útil OKLCH para ordenar tokens relacionados, especialmente en rampas de luminosidad o interpolaciones que no caen hacia gris tan fácilmente como ciertas mezclas rectangulares. El modelo mejora el trabajo, pero no es perfecto: cada paso necesita revisión visual en pantallas reales.
- Usa L para ordenar funciones claras y oscuras, recordando que pasos numéricos iguales solo aproximan pasos visuales iguales.
- Usa C para controlar la distancia al eje neutro; valores mayores dan más color hasta que limita el gamut de salida.
- Usa H para mantener una familia próxima a un tono o elegir una ruta explícita entre tonos durante la interpolación.
- Trata L, C y H como coordenadas de paleta, no como afirmaciones de accesibilidad. WCAG usa luminancia relativa derivada de los colores sRGB finalmente renderizados.
- Registra el gamut previsto y el fallback junto a la fuente OKLCH para reproducir el token entre navegadores, herramientas y pantallas.
Escribe la sintaxis sin caer en la trampa del porcentaje de chroma
La sintaxis moderna usa espacios y una barra opcional antes de alpha: oklch(L C H / A). Las comas son inválidas. La luminosidad admite un número de 0 a 1 o un porcentaje de 0% a 100%. Chroma suele escribirse como número; CSS Color 4 establece que 100% de chroma equivale a 0,4, de modo que 25% significa 0,1 y no 0,25. Chroma no posee un máximo universal: alrededor de 0,5 cubre el rango práctico, pero el límite útil depende de luminosidad, tono y gamut. Los valores negativos se limitan a cero.
:root {
--brand: oklch(70% 0.16 30);
--brand-same-chroma: oklch(70% 40% 30); /* 40% of 0.4 = 0.16 */
--brand-muted: oklch(70% 0.08 30);
--brand-overlay: oklch(70% 0.16 30 / 65%);
}| Coordenada | Forma CSS | Significado práctico | Límite importante |
|---|---|---|---|
| L | 70% o 0.7 | Coordenada de luminosidad perceptiva | No es luminancia relativa WCAG |
| C | 0.16 o 40% | Distancia al eje neutro | 100% equivale a 0.4 |
| H | 30 o 30deg | Ángulo polar de tono | Sin efecto cuando chroma es prácticamente cero |
| A | / 65% | Opacidad antes de componer | El contraste depende del fondo |
Construye una rampa de luminosidad y prueba cada primer plano
La siguiente rampa mantiene chroma en 0,08 y tono en 30 mientras L cambia de 35% a 85%. Los HEX son aproximaciones sRGB de 8 bits calculadas con las matrices Oklab de CSS Color 4 y redondeadas al canal más cercano. Después se recalcula el contraste de cada HEX con la fórmula WCAG. AA para texto normal exige 4,5:1. La separación es esencial: L estructura la rampa, pero el color final compuesto aporta la evidencia de accesibilidad.
| OKLCH | sRGB de 8 bits | Texto negro | Texto blanco | Elección AA normal |
|---|---|---|---|---|
| oklch(35% 0.08 30) | #5D2820 | 1.79:1 | 11.73:1 | Blanco |
| oklch(45% 0.08 30) | #7C433A | 2.72:1 | 7.72:1 | Blanco |
| oklch(55% 0.08 30) | #9B5F55 | 4.16:1 | 5.05:1 | Blanco |
| oklch(65% 0.08 30) | #BB7D72 | 6.29:1 | 3.34:1 | Negro |
| oklch(75% 0.08 30) | #DC9B90 | 9.13:1 | 2.30:1 | Negro |
| oklch(85% 0.08 30) | #FEBBAF | 12.94:1 | 1.62:1 | Negro |
- En este tono y chroma, el primer plano cambia entre L 55% y L 65%; no existe un corte universal de luminosidad OKLCH.
- L 55% no hace que negro supere AA para texto normal aunque parezca el centro de la rampa: la relación es 4,16:1.
- Conserva relaciones sin redondear para decidir y redondea solo lo mostrado en documentación.
- Prueba estados hover, selected y disabled, degradados y transparencias después de componer todas las capas.
- Un HEX aproximado sirve para revisar sRGB, pero no puede codificar exactamente un color original exterior a sRGB.
Aumenta chroma hasta que limite el gamut de destino
Chroma no tiene un máximo seguro único para todas las paletas. Con L 70% y H 30, los valores hasta C 0,19 permanecen dentro de sRGB en este cálculo. C 0,20 ya queda fuera de sRGB pero dentro de Display P3, y C 0,24 sigue siendo un color OKLCH válido que ese gamut más amplio puede contener. Otra luminosidad o tono alcanza el límite en otro punto. Fuera de sRGB no existe un HEX de 8 bits exacto; sustituirlo por un HEX recortado ocultaría el cambio de gamut y podría alterar tono o luminosidad.
| OKLCH con L 70%, H 30 | Aproximación sRGB de 8 bits | sRGB | Display P3 | Interpretación |
|---|---|---|---|---|
| C 0.00 | #9E9E9E | Dentro | Dentro | Neutro; tono sin efecto |
| C 0.08 | #CB8C81 | Dentro | Dentro | Color apagado |
| C 0.16 | #F17260 | Dentro | Dentro | Color sRGB intenso |
| C 0.19 | #FE6652 | Dentro | Dentro | Cerca de este límite sRGB |
| C 0.20 | — | Fuera | Dentro | Sin representación HEX exacta |
| C 0.24 | — | Fuera | Dentro | Resultado de gamut amplio |
Separa el fallback de sintaxis del gamut mapping
Fallback y gamut mapping resuelven problemas distintos. El fallback ofrece a software antiguo una declaración comprensible. Un navegador compatible puede interpretar OKLCH y aun así necesitar mapear el color al gamut real de la pantalla. Usa @supports si una propiedad personalizada debe ser válida como unidad: guardar en ella un color no compatible puede dejar válida la declaración hasta la sustitución y hacer fallar la propiedad consumidora en vez de recuperar un valor anterior. El bloque condicional evita esa trampa.
:root {
--brand: #FE6652;
}
@supports (color: oklch(70% 0.20 30)) {
:root {
--brand: oklch(70% 0.20 30);
}
}
.button {
color: #000000;
background: var(--brand);
}- Elige el fallback deliberadamente; #FE6652 es el último paso sRGB del ejemplo, no una afirmación de identidad con C 0,20.
- Indica si el token preferido apunta a sRGB, Display P3 u otro gamut y pruébalo en pantallas que representen cada ruta.
- No recortes previamente todos los tokens para forzar coincidencias entre herramientas: perderías la fuente amplia y podrías crear rampas irregulares.
- Espera que el navegador o pipeline haga gamut mapping al producir la salida; inspecciona el resultado y no presupongas un algoritmo eterno.
- Recalcula el contraste del fallback y del color preferido mapeado, sin heredar una sola relación desde las coordenadas fuente.
Elige deliberadamente el espacio de interpolación y la ruta de tono
El espacio entre extremos importa tanto como su notación. Los degradados CSS y color-mix() pueden solicitar interpolación OKLCH. Un espacio polar puede conservar chroma mejor que una mezcla rectangular que atraviesa un centro apagado, pero existen varias rutas alrededor del círculo de tono. Las rutas corta y larga pueden producir familias intermedias completamente distintas; increasing y decreasing fijan la dirección. Los intermedios también pueden salir del gamut aunque ambos extremos se muestren, por lo que la rampa terminada requiere controles de gamut y contraste.
.spectrum {
background: linear-gradient(
90deg in oklch shorter hue,
oklch(70% 0.16 30),
oklch(70% 0.16 280)
);
}
:root {
--brand-soft: color-mix(
in oklch,
oklch(70% 0.16 30) 35%,
white
);
}- Usa Oklab para una interpolación perceptiva recta y OKLCH cuando sea más importante controlar una ruta polar o conservar chroma.
- Especifica shorter, longer, increasing o decreasing hue cuando la ruta cambie el significado del producto; no dependas de un valor predeterminado accidental.
- Muestrea paradas intermedias: revisar solo extremos no revela un punto medio fuera del gamut o con poco contraste.
- Mezclar con blanco cambia más que L en un modelo polar. Si solo debe variar una coordenada, genera tokens OKLCH explícitos.
- Mantén los colores derivados en el mismo pipeline documentado para que vistas de diseño, CSS, capturas y auditorías usen idénticas reglas.
Publica tokens OKLCH con evidencia auditable
Una paleta OKLCH de producción debe poder revisarse sin reconstruir decisiones ocultas de la herramienta de diseño. Guarda las coordenadas fuente con precisión útil, identifica el gamut, conserva un fallback intencional y exporta evidencia calculada junto a cada token semántico. Después prueba los estados renderizados reales. Así se mantienen las ventajas perceptivas del modelo y el soporte del navegador, el gamut y la accesibilidad se convierten en entradas ordinarias de ingeniería.
:root {
--action-strong: oklch(55% 0.08 30);
--action: oklch(65% 0.08 30);
--action-soft: oklch(85% 0.08 30);
--on-action-strong: #FFFFFF; /* 5.05:1 on #9B5F55 */
--on-action: #000000; /* 6.29:1 on #BB7D72 */
--on-action-soft: #000000; /* 12.94:1 on #FEBBAF */
}- Distingue L de la luminancia relativa WCAG y C de la saturación HSL.
- Documenta la normalización de porcentajes, especialmente que C 100% equivale a 0,4 en CSS.
- Trata el tono como ineficaz en neutros y evita etiquetas inestables basadas en una coordenada invisible.
- Registra qué tokens están dentro de sRGB, cuáles exigen un gamut amplio y qué fallback se entrega si falla la ruta preferida.
- Conserva precisión suficiente para convertir, pero publica HEX redondeado solo como aproximación sRGB de 8 bits identificada.
- Prueba el contraste de los colores finalmente compuestos; alpha, degradados, overlays y gamut mapping pueden cambiar lo visible.
- Revisa por separado puntos intermedios, foco, bordes, hover, selected, temas claro y oscuro y forced colors.
- Enlaza la especificación y el método de conversión para reproducir y explicar futuros cambios.
Fuentes primarias
Las afirmaciones de este artículo se comprueban con estas especificaciones publicadas.
- W3C CSS Color 4 — introducción a Oklab y OkLCh
- W3C CSS Color 4 — especificación de Oklab y OkLCh
- W3C CSS Color 4 — adaptación al gamut
- W3C CSS Color 4 — métodos de interpolación de color
- W3C CSS Images 4 — interpolación de color en degradados
- W3C CSS Color 5 — color-mix()
- W3C CSS Conditional 3 — @supports
- W3C WCAG 2.2 — luminancia relativa
- W3C WCAG 2.2 — Contraste (mínimo)