CSS color-mix()

Adam Argyle
Adam Argyle

La función color-mix() de CSS te permite mezclar colores, en cualquiera de los espacios de color admitidos, directamente desde tu CSS.

Navegadores compatibles

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 16.2.

Origen

Antes del color-mix(), para oscurecer, aclarar o reducir la saturación de un color, los desarrolladores usaban preprocesadores de CSS o calc() en los canales de color.

Antes con SCSS
.color-mixing-with-sass {
  /* Sass: equally mix red with white */
  --red-white-mix: color.mix(red, white);
}

Sass hizo un gran trabajo para mantenerse por delante de la especificación de CSS de colores. Sin embargo, no ha habido una forma real de mezclar colores en CSS. Para acercarte, debes hacer cálculos de valores de color parciales. Este es un ejemplo reducido de cómo CSS puede simular la combinación en la actualidad:

Antes con HSL
.color-mixing-with-vanilla-css-before {
  --lightness: 50%;
  --red: hsl(0 50% var(--lightness));

  /* add "white" to red
     by adding 25% to the lightness channel
  */
  --lightred: hsl(0 50% calc(var(--lightness) + 25%);
}

color-mix() brinda la posibilidad de mezclar colores en CSS. Los desarrolladores pueden elegir en qué espacio de color mezclar los colores y qué tan dominante debe ser cada color en la combinación.

Después
.color-mixing-after {
  /* equally mix red with white */
  --red-white-mix: color-mix(in oklab, red, white);

  /* equally mix red with white in srgb */
  --red-white-mix-srgb: color-mix(in srgb, red, white);
}

Eso es lo que queremos. Flexibilidad, potencia y APIs con todas las funciones. ámalo

Mezcla de colores en CSS

CSS existe en un mundo con varios espacios y gamas de colores, por lo que no es opcional especificar el espacio de color para la mezcla. Además, los diferentes espacios de color pueden cambiar drásticamente los resultados de una combinación, por lo que conocer los efectos de un espacio de color te ayudará a obtener los resultados que necesitas.

Para obtener una introducción interactiva, prueba esta herramienta de color-mix(): - Explora los efectos de cada espacio de color. - Explora los efectos de la interpolación de tono cuando se mezclan en un espacio de color cilíndrico (lch, oklch, hsl y hwb). - Para cambiar los colores que se mezclan, haz clic en cualquiera de los dos cuadros de color de la parte superior. - Utiliza el control deslizante para modificar la proporción de mezcla. - El código CSS color-mix() generado está disponible en la parte inferior.

Mezcla en los diferentes espacios de color

El espacio de color predeterminado para la combinación (y los gradientes) es oklab. Proporciona resultados coherentes. También puedes especificar espacios de color alternativos para adaptar la combinación a tus necesidades.

Tomemos black y white como ejemplo. El espacio de color en el que se mezclan no hará una gran diferencia, ¿verdad? Todo lo contrario.

color-mix(in srgb, black, white);
color-mix(in srgb-linear, black, white);
color-mix(in lch, black, white);
color-mix(in oklch, black, white);
color-mix(in lab, black, white);
color-mix(in oklab, black, white);
color-mix(in xyz, black, white);
7 espacios de color (sRGB, linear-sRGB, lch, oklch, lab, oklab y xyz) muestran los resultados de la combinación de blanco y negro. Se muestran aproximadamente 5 tonos diferentes, lo que demuestra que cada espacio de color incluso se mezclará con un gris de manera diferente.
Probar la demostración

¡Tiene un gran efecto!

Tomemos blue y white para dar otro ejemplo. Elegí esto específicamente porque es un caso en el que la forma de un espacio de color puede afectar los resultados. En este caso, la mayoría de los espacios de color se vuelven púrpuras mientras pasan de blanco a azul. También muestra cómo oklab es un espacio de color tan confiable para la combinación, es lo más cercano a las expectativas de la mayoría de las personas de combinar blanco y azul (sin morado).

color-mix(in srgb, blue, white);
color-mix(in srgb-linear, blue, white);
color-mix(in lch, blue, white);
color-mix(in oklch, blue, white);
color-mix(in lab, blue, white);
color-mix(in oklab, blue, white);
color-mix(in xyz, blue, white);
7 espacios de color (sRGB, sRGB lineal, lch, oklch, lab, oklab y xyz) que muestran resultados diferentes. Muchas son de color rosa o morado, y pocas siguen siendo azules.
Probar la demostración

Aprender los efectos de un espacio de color con color-mix() es un gran conocimiento para hacer gradientes. La sintaxis de Color 4 también permite que los gradientes especifiquen el espacio de color, en el que un gradiente muestra la combinación en un área del espacio.

.black-to-white-gradient-in-each-space {
  --srgb: linear-gradient(to right in srgb, black, white);
  --srgb-linear: linear-gradient(to right in srgb-linear, black, white);
  --lab: linear-gradient(to right in lab, black, white);
  --oklab: linear-gradient(to right in oklab, black, white);
  --lch: linear-gradient(to right in lch, black, white);
  --oklch: linear-gradient(to right in oklch, black, white);
  --hsl: linear-gradient(to right in hsl, black, white);
  --hwb: linear-gradient(to right in hwb, black, white);
  --xyz: linear-gradient(to right in xyz, black, white);
  --xyz-d50: linear-gradient(to right in xyz-d50, black, white);
  --xzy-d65: linear-gradient(to right in xyz-d65, black, white);
}
Gradientes de negro a blanco en diferentes espacios de color.
Probar la demostración

Si te preguntas qué espacio de color es "el mejor", no hay ninguno. Por eso hay tantas opciones. Tampoco se inventarían nuevos espacios de color (consulta oklch y oklab) si uno fuera “el mejor”. Cada espacio de color puede tener un momento único para brillar y ser la opción correcta.

Por ejemplo, si deseas obtener un resultado de combinación vibrante, usa hsl o hwb. En la siguiente demostración, se mezclan dos colores brillantes (magenta y lima), y hsl y hwb producen un resultado brillante, mientras que srgb y oklab producen colores no saturados.

La combinación se obtiene como se describe en el párrafo anterior.
Probar la demostración

Si quieres coherencia y sutileza, usa oklab. En la siguiente demostración, que combina el azul y el negro, hsl y hwb producen colores demasiado vibrantes y con un tono desplazado, mientras que srgb y oklab producen un azul más oscuro.

La combinación genera los resultados como se describe en el párrafo anterior.
Probar la demostración

Pasa cinco minutos en el área de pruebas de color-mix(), prueba diferentes colores y espacios, y comenzarás a tener una idea de las ventajas de cada espacio. También esperamos que haya más orientación sobre los espacios de color a medida que todos nos adaptemos a sus posibilidades en nuestras interfaces de usuario.

Cómo ajustar el método de interpolación de tono

Si elegiste mezclar en un espacio de color cilíndrico, en esencia, cualquier espacio de color con un canal de tono h que acepte un ángulo, puedes especificar si la interpolación va de shorter, longer, decreasing y increasing. Si quieres obtener más información, consulta esta Guía de colores HD.

Este es el mismo ejemplo de combinación de azul a blanco, pero esta vez, solo se muestra en los espacios cilíndricos con diferentes métodos de interpolación de tono.

La combinación se obtiene como se describe en el párrafo anterior.
Probar la demostración

Este es otro Codepen que hice para ayudar a visualizar la interpolación de tono, pero específicamente para los gradientes. Creo que esto te ayudará a comprender cómo cada espacio de color produce su resultado de combinación cuando se especifica la interpolación de tono. ¡Analízalo!

Combinación con diferentes sintaxis de colores

Hasta ahora, combinamos principalmente colores con nombres de CSS, como blue y white. La combinación de colores de CSS está lista para combinar colores de dos espacios de color diferentes. Esta es otra razón por la que es clave especificar el espacio de color para la combinación, ya que establece el espacio común para cuando los dos colores no están en el mismo espacio.

color-mix(in oklch, hsl(200deg 50% 50%), color(display-p3 .5 0 .5));

En el ejemplo anterior, hsl y display-p3 se convertirán en oklch y, luego, se mezclarán. Muy interesante y flexible.

Cómo ajustar las proporciones de mezcla

No es muy probable que cada vez que mezcles quieras partes iguales de cada color, como se mostró en la mayoría de los ejemplos hasta ahora. Buenas noticias, hay una sintaxis para articular cuánto de cada color debe verse en la mezcla resultante.

Para comenzar con este tema, aquí tienes una muestra de combinaciones que son equivalentes (y de la especificación):

.ratios-syntax-examples {
  /* omit the percentage for equal mixes */
  color: color-mix(in lch, purple, plum);
  color: color-mix(in lch, plum, purple);

  /* percentage can go on either side of the color */
  color: color-mix(in lch, purple 50%, plum 50%);
  color: color-mix(in lch, 50% purple, 50% plum);

  /* percentage on just one color? other color gets the remainder */
  color: color-mix(in lch, purple 50%, plum);
  color: color-mix(in lch, purple, plum 50%);

  /* percentages > 100% are equally clamped */
  color: color-mix(in lch, purple 80%, plum 80%);
  /* above mix is clamped to this */
  color: color-mix(in lch, purple 50%, plum 50%);
}

Estos ejemplos son útiles para entender bien los casos extremos. El primer conjunto de ejemplos muestra cómo el 50% no es obligatorio, pero se puede especificar de forma opcional. En el último ejemplo, se muestra un caso interesante para cuando las proporciones superan el 100% cuando se suman, se limitan igualmente al 100% total.

También observa que, si solo un color especifica una proporción, se supone que el otro es el resto hasta el 100%. Estos son algunos ejemplos más que ayudan a ilustrar este comportamiento.

color-mix(in lch, purple 40%, plum) /* plum assigned 60% */
color-mix(in lch, purple, 60% plum) /* purple assigned 40% */
color-mix(in lch, purple 40%, plum 60%) /* no auto assignments */

En estos ejemplos, se ilustran dos reglas: 1. Cuando las proporciones superan el 100%, se limitan y se distribuyen de manera equitativa. 1. Cuando solo se proporciona una proporción, el otro color se establece en 100 menos esa proporción.

La última regla es un poco menos obvia. ¿Qué sucede si se proporcionan porcentajes para ambos colores y no suman el 100%?

color-mix(in lch, purple 20%, plum 20%)

Esta combinación de un color-mix() genera transparencia, transparencia 40%. Cuando las proporciones no suman el 100%, la combinación resultante no será opaca. Ninguno de los colores se mezclará por completo.

Anidación color-mix()

Al igual que en todo CSS, el anidamiento se maneja bien y como se espera. Las funciones internas se resolverán primero y mostrarán sus valores en el contexto superior.

color-mix(in lch, purple 40%, color-mix(plum, white))

No dudes en anidar todo lo que necesites para obtener el resultado que deseas.

Cómo crear un esquema de colores claros y oscuros

¡Construyamos esquemas de colores con color-mix()!

Un esquema de colores básico

En el siguiente CSS, se crean un tema claro y uno oscuro en función de un color hexadecimal de la marca. El tema claro crea dos colores de texto azul oscuro y un color de superficie de fondo blanco muy claro. Luego, en una consulta de medios de preferencia oscura, se asignan colores nuevos a las propiedades personalizadas para que el fondo sea oscuro y los colores del texto sean claros.

:root {
  /* a base brand color */
  --brand: #0af;

  /* very dark brand blue */
  --text1: color-mix(in oklab, var(--brand) 25%, black);
  --text2: color-mix(in oklab, var(--brand) 40%, black);

  /* very bright brand white */
  --surface1: color-mix(in oklab, var(--brand) 5%, white);
}

@media (prefers-color-scheme: dark) {
  :root {
    --text1: color-mix(in oklab, var(--brand) 15%, white);
    --text2: color-mix(in oklab, var(--brand) 40%, white);
    --surface1: color-mix(in oklab, var(--brand) 5%, black);
  }
}

Para lograr todo esto, se mezcla el blanco o el negro con un color de marca.

Esquema de colores intermedio

Esto se puede llevar un paso más allá si se agregan más temas que los claros y oscuros. En la siguiente demostración, los cambios en el grupo de botones de selección actualizan un atributo en la etiqueta HTML [color-scheme="auto"], que luego habilita los selectores para aplicar condicionalmente un tema de color.

En esta demostración intermedia, también se muestra una técnica de temas de color en la que todos los colores del tema se enumeran en :root. Esto facilita ver todo junto y ajustarlo si es necesario. Más adelante en la hoja de estilo, puedes usar las variables a medida que están definidas. Esto evita tener que buscar manipulaciones de color en la hoja de estilo, ya que todas están contenidas en el bloque :root inicial.

Casos de uso más interesantes

Ana Tudor tiene una gran demostración con algunos casos de uso de estudio:

Depuración de color-mix() con DevTools

Las Herramientas para desarrolladores de Chrome ofrecen una gran compatibilidad con color-mix(). Reconoce y destaca la sintaxis, crea una vista previa de la combinación junto al estilo en el panel Estilos y permite elegir colores alternativos.

En Herramientas para desarrolladores, se verá de la siguiente manera:

Captura de pantalla de Chrome DevTools que inspecciona la sintaxis de color-mix.

¡Que disfruten mezclando!