CSS color-mix()

Adam Argyle
Adam Argyle

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

Navegadores compatibles

  • 111
  • 111
  • 113
  • 16.2

Origen

Antes de color-mix(), para oscurecer, aclarar o desaturar 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 al adelantarse a la especificación de CSS de color. Sin embargo, no existía una manera real de combinar colores en CSS. Para acercarte, debes hacer cálculos de valores de color parciales. A continuación, te mostramos un ejemplo reducido de cómo CSS puede simular la mezcla hoy en día:

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() ofrece la capacidad de combinar colores en CSS. Los desarrolladores pueden elegir el espacio de color que mezclan y el grado de dominante que debe tener cada color en la mezcla.

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 Me encanta.

Combinación de colores en CSS

CSS existe en un mundo espacio de color y gama de colores y, por este motivo, 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 mezcla, 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 color-mix(): - Explora los efectos de cada espacio de color. - Explora los efectos de la interpolación de matiz cuando se mezcla 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 superiores. - Usa el control deslizante para cambiar la proporción de mezcla. - Se generó el código CSS color-mix() disponible en la parte inferior.

Mezcla los distintos espacios de color

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

Tomemos como ejemplo black y white. El espacio de color que mezclan no marcará 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, xyz) cada uno muestra sus resultados de la combinación de blanco y negro. Se muestran aproximadamente 5 tonos diferentes, lo que demuestra que cada espacio de color se mezclará incluso con un gris de manera diferente.
Probar la demostración

¡Tiene un gran efecto!

Toma blue y white para 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, es que la mayoría de los espacios de color se vuelven púrpura mientras viajan del blanco al azul. También muestra por qué oklab es un espacio de color tan confiable para mezclar que es el más cercano a las expectativas de la mayoría de las personas con respecto a la mezcla de blanco y azul (sin púrpura).

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);
Se muestran 7 espacios de color (srgb, linear-srgb, lch, oklch, lab, oklab, xyz) cada uno con resultados diferentes. Muchas son de color rosa o púrpura, y otras, en realidad, son azules.
Probar la demostración

Aprender los efectos de un espacio de color con color-mix() también es un gran conocimiento para crear gradientes. La sintaxis del color 4 también permite que los gradientes especifiquen el espacio de color, en el que un gradiente muestra la mezcla en un área de 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. Es por eso que hay tantas opciones. Tampoco se inventarían nuevos espacios de color (consulta oklch y oklab), si uno de ellos fuera "el mejor". Cada espacio de color puede tener un momento único para brillar y ser la elección correcta.

Por ejemplo, si quieres un resultado de mezcla 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 vibrante, mientras que srgb y oklab producen colores insaturados.

La combinación se genera 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 azul y negro, hsl y hwb producen colores demasiado vibrantes y con cambios de tono, mientras que srgb y oklab producen un azul más oscuro.

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

Dedica cinco minutos a la zona de pruebas de color-mix() y prueba diferentes colores y espacios, y comenzarás a tener una idea de las ventajas de cada uno. Además, se espera que haya más orientación sobre los espacios de color a medida que todos nos ajustamos a sus posibles en nuestras interfaces de usuario.

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

Si elegiste mezclar un espacio de color cilíndrico (en esencia, cualquier espacio de color con un canal de matiz h que acepte un ángulo), puedes especificar si la interpolación debe ser shorter, longer, decreasing y increasing. Si quieres obtener más información, este tema se aborda en profundidad en esta Guía de colores en HD.

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

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

Aquí hay otro Codepen que hice para ayudar a visualizar la interpolación de tonos, pero específicamente para gradientes. Creo que esto te ayudará a comprender cómo cada espacio de color produce su resultado de mezcla cuando se especifica la interpolación de matiz. ¡Estudio!

Combinación con sintaxis de colores variables

Hasta ahora, mezclamos principalmente colores con nombres de CSS, como blue y white. La mezcla de colores de CSS está lista para mezclar colores que provienen de dos espacios de color diferentes. Esta es otra razón por la que es clave especificar el espacio de color para la mezcla, 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. Bastante genial y flexible.

Cómo ajustar las proporciones de mezcla

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

Para comenzar este tema, aquí tienes una muestra de combinaciones que son todas equivalentes (y según las especificaciones):

.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%);
}

Encontré estos ejemplos para ilustrar bien los casos límite. El primer conjunto de ejemplos muestra que el 50% no es necesario, pero se puede especificar de forma opcional. El último ejemplo muestra un caso interesante en el que, cuando las proporciones superan el 100% cuando se agregan, se restringen de manera equitativa al 100%.

Además, ten en cuenta que, si solo un color especifica una proporción, se supone que el otro es el 100% del resto. A continuación, te mostramos algunos ejemplos más para 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 */

Estos ejemplos ilustran dos reglas: 1. Cuando las proporciones superan el 100%, se restringen y se distribuyen de forma equitativa. 1. Cuando solo se proporciona una relació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 100%?

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

Esta combinación de un color-mix() da como resultado transparencia, y una 40% de transparencia. Cuando las proporciones no sumen el 100%, la mezcla resultante no será opaca. Ninguno de los colores se mezclará por completo.

color-mix() de período de prueba

Como sucede con todos los CSS, la anidación se controla 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 tanto como necesites para obtener el resultado que buscas.

Cómo crear un esquema de colores claro y oscuro

Compilemos esquemas de colores con color-mix().

Un esquema de colores básico

En el siguiente CSS, se crean temas claros y oscuros a partir de un color hexadecimal de la marca. El tema claro crea dos colores de texto azul oscuro y un color de superficie blanco muy claro. Luego, en una consulta de medios de preferencia oscura, a las propiedades personalizadas se les asignan colores nuevos 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);
  }
}

Todo esto se logra mezclando blanco o negro en un color de marca.

Esquema de colores intermedio

Puedes ir un paso más allá si agregas más que temas 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 a los selectores para aplicar condicionalmente un tema de color.

En esta demostración de nivel intermedio, también se muestra una técnica de aplicación de temas de color en la que todos los colores del tema se enumeran en :root. Esto hace que sea fácil ver todos juntos y ajustarse si es necesario. Más adelante en la hoja de estilo, puedes usar las variables a medida que se definen. De esta manera, se ahorra buscar en la hoja de estilo para las manipulaciones de color, ya que todas están incluidas en el bloque :root inicial.

Casos de uso más interesantes

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

Cómo depurar color-mix() con Herramientas para desarrolladores

Las Herramientas para desarrolladores de Chrome tienen una gran compatibilidad con color-mix(). Reconoce y destaca la sintaxis, crea una vista previa de la mezcla junto al diseño en el panel Styles y permite elegir colores alternativos.

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

Captura de pantalla de las Herramientas para desarrolladores de Chrome que inspeccionan la sintaxis de la combinación de colores.

¡Que disfruten de mezclarlos!