Sintaxis de Color Relativo en CSS Explicada
Si alguna vez has definido una docena de propiedades personalizadas solo para crear una versión semitransparente de tu color de marca, ya entiendes el problema que resuelve la sintaxis de color relativo de CSS. Esta característica te permite derivar nuevos colores directamente desde colores existentes dentro de cualquier función de color CSS moderna — sin preprocesadores, sin JavaScript, sin variables adicionales.
Puntos Clave
- La sintaxis de color relativo de CSS utiliza la palabra clave
frompara derivar nuevos colores desde un color de origen existente, exponiendo sus canales individuales como variables modificables. - Funciona con
rgb(),hsl(),hwb(),lab(),lch(),oklab()yoklch(). - OKLCH es el espacio de color preferido para la manipulación porque su canal de luminosidad es perceptualmente uniforme, produciendo resultados visualmente consistentes en todos los tonos.
- Los colores relativos se integran naturalmente en sistemas de diseño basados en tokens, permitiéndote definir un color base y derivar cada variante desde él sin preprocesadores ni pasos de compilación.
¿Qué es la Sintaxis de Color Relativo de CSS?
Los colores relativos de CSS, definidos en la especificación CSS Color Level 5, te permiten tomar un color existente — llamado el color de origen — y usar sus canales individuales como variables para construir un nuevo color. La adición clave es la palabra clave from.
Esta es la estructura básica:
color-function(from <origin-color> channel1 channel2 channel3)
Cuando el navegador encuentra from, convierte el color de origen al espacio de color objetivo, expone cada canal como una variable nombrada y te permite pasar esas variables — modificadas o sin cambios — como los valores de salida.
Esto funciona con las funciones de color CSS modernas como rgb(), hsl(), hwb(), lab(), lch(), oklab() y oklch().
Cómo Funciona la Sintaxis CSS from Color
Toma este ejemplo simple:
/* Origin color: green */
/* Channels exposed: r=0, g=128, b=0 */
color: rgb(from green r g b); /* outputs rgb(0 128 0) */
La salida es idéntica a la entrada aquí, pero el verdadero poder es que puedes modificar canales individuales usando calc():
/* Rotate the hue by 180 degrees to get the complement */
background: hsl(from blue calc(h + 180) s l);
/* Lighten by multiplying the lightness channel */
background: oklch(from blue calc(l * 1.25) c h);
/* Reduce opacity without a separate variable */
background: rgb(from lime r g b / 50%);
Los valores de los canales se resuelven como números simples dentro de la función, por lo que la aritmética con calc() funciona limpiamente sin desajustes de unidades.
Por Qué Vale la Pena Usar Colores Relativos OKLCH
No todos los espacios de color son iguales para la manipulación. HSL es familiar, pero su canal de luminosidad no es perceptualmente uniforme — ajustar l en la misma cantidad produce resultados visualmente inconsistentes en diferentes tonos.
OKLCH resuelve esto. Su canal de luminosidad es perceptualmente uniforme, lo que significa que un cambio de +0.1 se ve como el mismo paso visual independientemente del tono. Esto lo convierte en una opción sólida para generar tintes, sombras y pares de contraste accesibles.
Si no estás familiarizado con los espacios de color perceptuales, el modelo de color OKLab/OKLCH introducido por Björn Ottosson explica el razonamiento detrás de estos espacios de color más nuevos.
/* Darken by 25% */
background: oklch(from var(--color-primary) calc(l * 0.75) c h);
/* Generate a high-contrast text color */
color: oklch(from var(--color-primary) calc(l + 0.6) c h);
Ten en cuenta que el canal de luminosidad en OKLCH va de 0 a 1, por lo que un cambio de calc(l + 0.6) es sustancial. Los valores que exceden el rango válido son recortados automáticamente por el navegador.
Colores Relativos vs. color-mix()
Estas dos características de color CSS sirven propósitos diferentes. color-mix() mezcla dos colores juntos en una proporción especificada. Los colores relativos de CSS manipulan directamente los canales de un solo color de origen. Si necesitas un estado hover, una variante atenuada o un token con opacidad ajustada, la sintaxis relativa es la herramienta correcta. Si necesitas interpolar entre dos colores distintos, usa color-mix().
Discover how at OpenReplay.com.
Integración en un Sistema de Diseño Basado en Tokens
Aquí es donde los colores relativos de CSS realmente brillan. Define un token base, luego deriva cada variante desde él:
:root {
--color-primary: #3b82f6;
--color-primary-hover: oklch(from var(--color-primary) calc(l * 0.9) c h);
--color-primary-active: oklch(from var(--color-primary) calc(l * 0.8) c h);
--color-primary-disabled: oklch(from var(--color-primary) l c h / 0.5);
--color-on-primary: oklch(from var(--color-primary) calc(l + 0.6) c h);
}
Cambia --color-primary y cada token derivado se actualiza automáticamente. Sin funciones de Sass, sin paso de compilación.
Compatibilidad con Navegadores
La sintaxis de color relativo es compatible con versiones modernas de Chromium, Firefox y Safari. Usa @supports para protegerla de forma segura:
@supports (color: rgb(from white r g b)) {
/* relative color syntax is available */
}
Para navegadores que carecen de soporte, proporciona un color de respaldo antes de la declaración de color relativo. La cascada asegura que los navegadores antiguos usen el valor estático mientras que los navegadores modernos lo sobrescriben:
.button {
background: #3b82f6;
background: oklch(from var(--color-primary) calc(l * 0.9) c h);
}
Conclusión
La sintaxis de color relativo de CSS reemplaza toda una categoría de lógica de preprocesador con un patrón único y legible. Elige OKLCH para ajustes de luminosidad perceptualmente consistentes, usa hsl() cuando necesites control directo de saturación, y conecta todo a una propiedad personalizada para que toda tu paleta permanezca sincronizada desde un token de origen único.
Preguntas Frecuentes
Sí. Puedes pasar cualquier propiedad personalizada como color de origen usando var(). Por ejemplo, oklch(from var(--brand-color) calc(l * 0.8) c h) funciona como se espera. El navegador resuelve primero la variable, luego convierte el color resultante al espacio de color objetivo y expone sus canales.
El navegador recorta automáticamente los valores fuera de rango. Por ejemplo, si una expresión calc() empuja la luminosidad de OKLCH por encima de 1 o por debajo de 0, el navegador la recorta al rango válido. Esto significa que no necesitas proteger manualmente contra el desbordamiento en la mayoría de los casos.
El impacto en el rendimiento es insignificante para el uso típico. El navegador resuelve los colores relativos en tiempo de valor computado, similar a cómo resuelve calc() en otras propiedades. Necesitarías miles de declaraciones de color relativo en una sola página antes de que aparezca cualquier diferencia medible.
Las funciones de color relativo pueden encadenarse si el resultado de una transformación se resuelve en un valor de color válido. En la práctica, los desarrolladores a menudo asignan el resultado de un cálculo de color relativo a una propiedad personalizada y usan esa como color de origen para otra transformación, permitiendo múltiples pasos de manipulación de color mientras mantienen el código legible.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.