Kodokon kodokon.com

Colores y funciones avanzadas: oklch, color-mix, min/max

Aprovecha los espacios de color perceptuales, la sintaxis de color relativo y las funciones matemáticas tipadas para construir sistemas de diseño que el navegador calcula por ti.

10 min · 3 preguntas

Abrir esta lección en Kodokon

El defecto estructural de hsl(): su luminosidad no es perceptual. hsl(60 100% 50%) (amarillo) parece deslumbrante mientras que hsl(240 100% 50%) (azul) parece oscuro, con la misma L. oklch lo corrige: su componente L (0 a 1) mide la luminosidad percibida, C es el croma (saturación absoluta, 0 a aproximadamente 0.37) y H el ángulo de tono. Cambiar H con L constante preserva el brillo percibido: las variaciones de tu paleta se vuelven por fin predecibles. Combinado con la sintaxis de color relativo (from), el navegador deriva por sí mismo tus variantes hover, atenuadas u oscuras.

CSS
:root {
  --brand: oklch(0.65 0.19 255);
  --dark: oklch(from var(--brand) calc(l - 0.15) c h);
  --muted: oklch(from var(--brand) l calc(c / 2) h);
  --accent: oklch(from var(--brand) l c calc(h + 180));
}
Un único color de origen, tres derivados calculados: los canales l, c, h se exponen como variables locales.

oklch puede describir colores fuera de la gama sRGB, o incluso fuera de Display-P3. ¿Qué hace el navegador cuando la pantalla no puede mostrarlos? No un recorte brutal canal por canal: la especificación prescribe un mapeo de gama que reduce progresivamente el croma preservando la luminosidad y el tono, hasta que el color encaja en la gama de destino. Puedes apuntar explícitamente a las pantallas de gama amplia con @media (color-gamut: p3). Otra herramienta de mezcla: color-mix(), cuyo primer argumento - el espacio de interpolación - cambia realmente el resultado: una mezcla in srgb de azul y amarillo se vuelve gris, mientras que in oklch recorre tonos vivos.

CSS
.badge {
  background: color-mix(in oklch, crimson 70%, white);
  border-color: color-mix(
    in oklch,
    var(--brand),
    transparent 60%
  );
}
Mezclar con transparent produce una variante translúcida sin duplicar el color como rgba.

min(), max() y clamp() son funciones matemáticas tipadas: aceptan mezclar unidades incompatibles en tiempo de parseo (rem + vw) porque la resolución ocurre en tiempo de valor usado, una vez que se conoce el viewport. clamp(MIN, VAL, MAX) es estrictamente equivalente a max(MIN, min(VAL, MAX)) - una consecuencia de la especificación: si MIN supera a MAX, vence MIN. Para la tipografía fluida, incluye siempre un componente rem en el valor central: un font-size: clamp(1rem, 2.5vw, 3rem) sin rem ignoraría el zoom de texto del usuario, un auténtico problema de accesibilidad.

CSS
h1 {
  font-size: clamp(1.5rem, 1.1rem + 2vw, 3rem);
}
.sidebar {
  width: min(30%, 20rem);
  padding-left: max(1rem, env(safe-area-inset-left));
}
Tipografía fluida accesible y márgenes que respetan las muescas de las pantallas móviles.

Prueba de conocimientos

Comprueba que has retenido los puntos clave de esta lección.

  1. ¿Qué ventaja decisiva ofrece oklch frente a hsl?
    • Una sintaxis más corta de escribir
    • Una luminosidad L perceptualmente uniforme de un tono a otro
    • Una garantía de permanecer dentro de la gama sRGB
    • El único espacio de color que admite un canal alfa
  2. ¿Qué hace el navegador cuando un color oklch supera la gama de la pantalla?
    • Ignora la declaración y mantiene el color anterior
    • Aplica un mapeo de gama que reduce principalmente el croma
    • Recorta cada canal RGB de forma independiente, sin más procesamiento
  3. En clamp(MIN, VAL, MAX), ¿qué ocurre si el valor calculado de MIN supera a MAX?
    • La declaración se vuelve inválida y se ignora
    • MAX vence y limita el resultado
    • MIN vence, porque clamp se expande a max(MIN, min(VAL, MAX))