Функция CSS color-mix()
позволяет смешивать цвета в любом из поддерживаемых цветовых пространств прямо из CSS.
До появления color-mix()
для затемнения, осветления или обесцвечивания цвета разработчики использовали препроцессоры CSS или calc()
для цветовых каналов.
.color-mixing-with-sass { /* Sass: equally mix red with white */ --red-white-mix: color.mix(red, white); }
Sass проделал большую работу, опережая спецификацию CSS по цвету. Однако реального способа смешивания цветов в CSS не существовало. Чтобы приблизиться, вам нужно выполнить математические вычисления частичных значений цвета. Вот сокращенный пример того, как CSS может имитировать смешивание сегодня:
.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()
предоставляет возможность смешивать цвета в CSS. Разработчики могут выбирать, в каком цветовом пространстве они будут смешивать и насколько доминировать в смеси должен каждый цвет.
.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); }
Это то, чего мы хотим. Гибкость, мощность и полнофункциональные API. Любить это.
Смешивание цветов в CSS
CSS существует в мире с множеством цветовых пространств и цветовой гаммы , поэтому указывать цветовое пространство для смешивания необязательно. Более того, разные цветовые пространства могут радикально изменить результаты смешивания, поэтому знание эффектов цветового пространства поможет вам получить нужные результаты.
Для интерактивного введения попробуйте этот инструмент color-mix()
: - Изучите эффекты каждого цветового пространства. - Изучите эффекты интерполяции оттенков при смешивании в цилиндрическом цветовом пространстве ( lch
, oklch
, hsl
и hwb
). - Измените смешиваемые цвета, щелкнув любое из двух верхних цветовых полей. - Используйте ползунок, чтобы изменить соотношение смешивания. — Сгенерированный CSS-код color-mix()
доступен внизу.
Смешение различных цветовых пространств
Цветовое пространство по умолчанию для смешивания (и градиентов ) — oklab
. Он обеспечивает стабильные результаты. Вы также можете указать альтернативные цветовые пространства, чтобы адаптировать сочетание к вашим потребностям.
Возьмем, к примеру, black
- white
. Цветовое пространство, в котором они смешиваются, не будет иметь большого значения, не так ли? Неправильный.
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);
Это имеет большой эффект!
Возьмем еще один пример blue
и white
. Я выбрал этот вариант специально потому, что в этом случае форма цветового пространства может повлиять на результаты. В данном случае большинство цветовых пространств становятся фиолетовыми при переходе от белого к синему. Это также показывает, что oklab
является настолько надежным цветовым пространством для смешивания, что оно наиболее близко соответствует ожиданиям большинства людей в отношении смешивания белого и синего (без фиолетового).
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);
Изучение эффектов цветового пространства с помощью color-mix()
также является отличным знанием для создания градиентов . Синтаксис цвета 4 также позволяет градиентам указывать цветовое пространство, где градиент отображает смесь в определенной области пространства.
.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);
}
Если вам интересно, какое цветовое пространство «лучшее», то его нет. Вот почему существует так много вариантов! Также не было бы изобретено новых цветовых пространств (см. oklch
и oklab
), если бы одно из них было «лучшим». Каждое цветовое пространство может иметь уникальный момент, чтобы проявить себя и стать правильным выбором.
Например, если вам нужен яркий результат микса, используйте hsl или hwb. В следующей демонстрации два ярких цвета (пурпурный и салатовый) смешиваются вместе, и hsl и hwb дают яркий результат, а srgb и oklab дают ненасыщенные цвета.
Если вам нужна последовательность и тонкость, используйте oklab. В следующей демонстрации, в которой смешаны синий и черный цвета, hsl и hwb дают слишком яркие цвета со смещенными оттенками, а srgb и oklab дают более темный синий.
Потратьте пять минут на игровую площадку color-mix()
, тестируя разные цвета и пространства, и вы начнете чувствовать преимущества каждого пространства. Также ожидайте появления дополнительных рекомендаций по цветовым пространствам по мере того, как мы все приспосабливаемся к их возможностям в наших пользовательских интерфейсах.
Настройка метода интерполяции оттенка
Если вы выбрали смешивание в цилиндрическом цветовом пространстве, по сути, в любом цветовом пространстве с каналом оттенка h
, который принимает угол, вы можете указать, будет ли интерполяция shorter
, longer
, decreasing
или increasing
. Если вы хотите узнать больше, это хорошо описано в Руководстве по цвету HD .
Вот тот же пример сочетания синего и белого, но на этот раз только в цилиндрических пространствах с разными методами интерполяции оттенков.
Вот еще один Codepen, который я сделал, чтобы помочь визуализировать интерполяцию оттенков, но специально для градиентов. Я считаю, что это поможет вам понять, как каждое цветовое пространство дает результат смешивания, когда указана интерполяция оттенков, хотя изучите это!
Смешивание с различными цветовыми синтаксисами
До сих пор мы в основном смешивали цвета с именами CSS, например blue
и white
. Смешение цветов CSS позволяет смешивать цвета из двух разных цветовых пространств. Это еще одна причина, по которой важно указать цветовое пространство для смешивания, поскольку оно устанавливает общее пространство, когда два цвета не находятся в одном и том же пространстве.
color-mix(in oklch, hsl(200deg 50% 50%), color(display-p3 .5 0 .5));
В предыдущем примере hsl
и display-p3
будут преобразованы в oklch
, а затем смешаны. Довольно круто и гибко.
Регулировка пропорций смешивания
Маловероятно, что каждый раз, когда вы смешиваете, вам нужны равные части каждого цвета, как показано в большинстве примеров. Хорошие новости: существует синтаксис, позволяющий определить, сколько каждого цвета должно быть видно в полученном миксе.
Чтобы начать эту тему, вот пример миксов, которые все эквивалентны (и соответствуют спецификации ):
.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%);
}
Я считаю, что эти примеры хорошо освещают крайние случаи. Первый набор примеров показывает, что 50% не требуется, но может быть указано дополнительно. Последний пример показывает интересный случай: когда коэффициенты при суммировании превышают 100%, они одинаково фиксируются до 100%.
Также обратите внимание: если только один цвет определяет соотношение, второй считается остатком от 100%. Вот еще несколько примеров, которые помогут проиллюстрировать такое поведение.
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 */
Эти примеры иллюстрируют два правила: 1. Когда коэффициенты превышают 100%, они фиксируются и распределяются поровну. 1. Если указано только одно соотношение, для другого цвета устанавливается значение 100 минус это соотношение.
Последнее правило немного менее очевидно; что произойдет, если для обоих цветов указаны проценты, но в сумме они не составят 100%?
color-mix(in lch, purple 20%, plum 20%)
Эта комбинация color-mix()
приводит к прозрачности, прозрачности 40%
. Если в сумме соотношения не достигают 100%, полученная смесь не будет непрозрачной. Ни один из цветов не будет полностью перемешан.
Вложение color-mix()
Как и во всем CSS, вложение обрабатывается хорошо и как и ожидалось; внутренние функции сначала разрешатся и вернут свои значения в родительский контекст.
color-mix(in lch, purple 40%, color-mix(plum, white))
Не стесняйтесь вкладывать столько, сколько вам нужно, чтобы получить результат, к которому вы стремитесь.
Построение светлой и темной цветовой схемы
Давайте построим цветовые схемы с помощью color-mix()
!
Базовая цветовая схема
В следующем CSS-коде светлая и темная темы создаются на основе шестнадцатеричного цвета бренда. Светлая тема создает два темно-синих цвета текста и очень светлый белый цвет фоновой поверхности. Затем в медиазапросе с темными предпочтениями пользовательским свойствам назначаются новые цвета, поэтому фон становится темным, а цвета текста — светлыми.
: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);
}
}
Все это достигается путем смешивания белого или черного цвета с цветом бренда.
Промежуточная цветовая гамма
Это можно сделать еще дальше, добавив больше, чем светлые и темные темы. В следующей демонстрации изменения в группе переключателей обновляют атрибут HTML-тега [color-scheme="auto"]
который затем позволяет селекторам условно применять цветовую тему.
В этой промежуточной демонстрации также показан метод цветовой темы, при котором все цвета темы перечислены в :root
. Это позволяет легко видеть их все вместе и при необходимости корректировать. Позже в таблице стилей вы можете использовать переменные в том виде, в котором они определены. Это избавляет от необходимости искать в таблице стилей манипуляции с цветом, поскольку все они содержатся в исходном блоке :root
.
Более интересные варианты использования
У Аны Тюдор есть отличная демонстрация с несколькими вариантами использования для изучения:
Отладка color-mix() с помощью DevTools
Chrome DevTools имеет отличную поддержку color-mix()
. Он распознает и выделяет синтаксис, создает предварительный просмотр микса рядом со стилем на панели «Стили» и позволяет выбирать альтернативные цвета.
В DevTools это будет выглядеть примерно так:
Всем приятного смешивания!