Функция 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(), также полезно для создания градиентов. Синтаксис Color 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%.
Обратите внимание, что если соотношение указано только для одного цвета, то для другого оно будет рассчитано автоматически. Вот ещё несколько примеров, иллюстрирующих это поведение.
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() с помощью инструментов разработчика
В инструментах разработчика Chrome есть отличная поддержка color-mix(). Она распознает и выделяет синтаксис, создает предварительный просмотр микса прямо рядом со стилем на панели "Стили" и позволяет выбирать альтернативные цвета.
В DevTools это будет выглядеть примерно так:

Удачного микширования!