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 compatibles directamente desde tu CSS.

Navegadores compatibles

  • 111
  • 111
  • 113
  • 16.2

Origen

Antes de 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 color de CSS. Sin embargo, no existe una forma real de mezclar colores en CSS. Para acercarte, debes hacer cálculos matemáticos de valores de color parciales. A continuación, se muestra un ejemplo reducido de cómo CSS puede simular la mezcla actual:

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 capacidad de combinar colores a CSS. Los desarrolladores pueden elegir qué espacio de color mezclarán y cuán dominante debería ser 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 espacio de color múltiple y un mundo de gamut de colores y, por este motivo, no es opcional especificar el espacio de color para mezclar. 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 matices al mezclar 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. - Código CSS color-mix() generado disponible en la parte inferior.

Combinación de diversos espacios de color

El espacio de color predeterminado para mezclar (y gradientes) es oklab. Proporciona resultados coherentes. También puedes especificar espacios de color alternativos para personalizar la mezcla según tus necesidades.

Tomemos como ejemplo a 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);
Los 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 se mezclará incluso con un gris de manera diferente.
Probar la demostración

¡Tiene un gran efecto!

Toma a 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 van 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 lo más cercano a las expectativas de la mayoría de las personas de mezclar 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);
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, mientras que otras aún son azules.
Probar la demostración

Aprender los efectos de un espacio de color con color-mix() es un gran conocimiento para crear gradientes también. La sintaxis del color 4 también permite que los gradientes especifiquen el espacio de color, donde un gradiente muestra la mezcla sobre 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. Por eso, 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 obtener un resultado de mezcla vibrante, usa hsl o hwb. En la siguiente demostración, se mezclan dos colores brillantes (magenta y lima), y ambos hsl y hwb producen un resultado llamativo, mientras que srgb y oklab producen colores insaturados.

La mezcla se produce 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 mezcla se produce 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 en un espacio de color cilíndrico, básicamente cualquier espacio de color con un canal de matiz h que acepte un ángulo, puedes especificar si la interpolación es shorter, longer, decreasing y increasing. Si quieres obtener más información, consulta la Guía de colores de HD.

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

La mezcla se produce 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 matiz, 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 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 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.

Ajustar las proporciones de mezcla

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

Para comenzar con este tema, aquí hay 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%);
}

Tengo estos ejemplos para iluminar bien los casos límite. En el primer conjunto de ejemplos, se muestra que el 50% no es necesario, pero se puede especificar de forma opcional. El último ejemplo muestra un caso interesante en el que las proporciones superan el 100% cuando se agregan, y se limitan de manera equitativa, hasta alcanzar el 100%.

Además, ten en cuenta que si solo un color especifica una proporción, se supone que el otro será el 100% restante. Estos son algunos ejemplos más que ayudarán 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 */

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

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

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

Período de prueba: color-mix()

Como con todo CSS, el anidamiento se maneja de forma correcta y como se espera; las funciones internas se resolverán primero y mostrarán sus valores al contexto superior.

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

Siéntete libre de anidar tanto como necesites para obtener el resultado que estás buscando.

Creación de 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 temas aparte de los 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 que los selectores apliquen de forma condicional un tema de color.

En esta demostración intermedia, 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 verlos 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 estilo en el panel Styles y permite elegir colores alternativos.

En Herramientas para desarrolladores, se verá algo así:

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

¡Feliz mezclar a todos!