Функция CSS `color-mix()`
Базовая поддержка Широко доступна
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и во многих версиях браузеров. Она поддерживается браузерами с мая 2023 года.
Функциональная нотация color-mix() принимает одно или несколько значений color и возвращает результат их смешивания в заданном цветовом пространстве в заданной пропорции.
Синтаксис
/* Polar color space */ color-mix(in hsl, hsl(200 50 80), coral) color-mix(in hsl, hsl(200 50 80) 20%, coral 80%) /* Rectangular color space */ color-mix(in srgb, plum, #123456) color-mix(in lab, plum 60%, #123456 50%) /* With hue interpolation method */ color-mix(in lch increasing hue, hsl(200deg 50% 80%), coral) color-mix(in lch longer hue, hsl(200deg 50% 80%) 44%, coral 16%) /* With a color argument list */ color-mix(in oklab, teal) color-mix(in oklab, teal 20%, olive 30%, blue 50%) color-mix(in oklab, teal, olive, blue, purple)
Параметры
Функция color-mix( <color-interpolation-method>? , [ <color> && <percentage [0,100]>? ]#) принимает следующие параметры:
-
<color-interpolation-method>Необязательный - Задаёт метод интерполяции, который будет использоваться для смешивания цветов. Состоит из ключевого слова
in, за которым следует цветовое пространство (одно из цветовых пространств, перечисленных в формальном синтаксисе; по умолчанию используетсяoklab) и, необязательно,<hue-interpolation-method>, значение которого по умолчанию —shorter hue. -
color - Смешиваемый цвет; может быть любым допустимым значением
<color>. -
<percentage>Необязательный - Процентное значение, задающее долю соответствующего цвета в смешивании; может быть любым значением
<percentage>от0%до100%включительно.
Возвращаемое значение
Значение <color> — результат смешивания цветов в заданном <color-space>, в указанных пропорциях и с заданным направлением интерполяции оттенка.
Описание
Функция color-mix() позволяет смешивать одно или несколько значений color любого типа в определённом соотношении, в заданном цветовом пространстве и с использованием интерполяции оттенка по короткому или длинному пути. Браузеры поддерживают множество цветовых пространств; функция color-mix() позволяет смешивать широкий спектр цветов, не ограничиваясь цветовым пространством sRGB.
В этом демонстрационном примере можно выбрать два цвета — color-one и color-two — и смешать их, при необходимости задав процентное соотношение каждого цвета, цветовое пространство для смешивания и метод интерполяции. Исходные цвета показаны по краям, а смешанный цвет — посередине. Чтобы изменить цвет, щёлкните по нему и выберите новый цвет в появившемся средстве выбора цвета. Изменяйте процентные значения каждого цвета с помощью ползунков. Выберите цветовое пространство в раскрывающемся меню.
Выбор цветового пространства
Для получения желаемого результата важно выбрать подходящее цветовое пространство. Для одних и тех же смешиваемых цветов разные цветовые пространства могут быть более уместны в зависимости от сценария использования интерполяции.
- Если нужен результат физического смешивания цветных источников света, подойдут цветовые пространства CIE XYZ или srgb-linear, поскольку они линейны по интенсивности света.
- Если требуется равномерное перцептивное распределение цветов (например, в градиенте), подойдут цветовые пространства Oklab (и более старое Lab), поскольку они разработаны для перцептивной равномерности.
- Если при смешивании цветов нужно избежать их посерения, то есть максимально сохранить насыщенность на протяжении перехода, хорошо подойдут цветовые пространства Oklch (и более старое LCH).
- Используйте sRGB только в том случае, если нужно воспроизвести поведение конкретного устройства или программы, использующих sRGB. Цветовое пространство sRGB не является ни линейным по свету, ни перцептивно равномерным, поэтому результаты смешивания получаются хуже — например, цвета могут быть слишком тёмными или сероватыми.
Метод интерполяции цветов
<color-interpolation-method> задаёт метод интерполяции, который будет использоваться для смешивания цветов. Он состоит из ключевого слова in и цветового пространства, в котором следует смешивать цвета. Цветовое пространство должно быть одним из доступных пространств, перечисленных в формальном синтаксисе. В зависимости от используемого цветового пространства можно дополнительно указать, чтобы интерполяция оттенка выполнялась по длинному или короткому пути.
К категории <rectangular-color-space> относятся srgb, srgb-linear, display-p3, a98-rgb, prophoto-rgb, rec2020, lab, oklab, xyz, xyz-d50 и xyz-d65.
К категории <polar-color-space> относятся hsl, hwb, lch и oklch. В этих случаях после названия цветового пространства можно дополнительно указать <hue-interpolation-method>. По умолчанию используется shorter hue, но также можно указать longer hue, increasing hue или decreasing hue.
Цветовое пространство и метод интерполяции по умолчанию
При смешивании цветов без указания цветового пространства или метода интерполяции оттенка используется цветовое пространство oklab, а в качестве метода интерполяции оттенка — shorter.
Следующие три объявления эквивалентны:
background-color: color-mix(red, blue); background-color: color-mix(in oklab, red, blue); background-color: color-mix(in oklab shorter hue, red, blue);
Процентные значения цветов
Для каждого цвета можно указать значение <percentage> от 0% до 100%, определяющее его долю в смешивании. Если сумма указанных процентных значений не равна 100%, они нормализуются.
При смешивании двух цветов их процентные значения (будем обозначать их как p1 и p2) нормализуются следующим образом:
- Если не указаны ни
p1, ниp2, тоp1 = p2 = 50%. - Если
p1не указано, тоp1 = 100% - p2. - Если
p2не указано, тоp2 = 100% - p1. - Если
p1 = p2 = 0%, функция недопустима. - Если
p1 + p2 ≠ 100%, тоp1' = p1 / (p1 + p2)иp2' = p2 / (p1 + p2), гдеp1'иp2'— результаты нормализации.- Если
p1 + p2 < 100%, к результирующему цвету применяется альфа-множительp1 + p2. Это похоже на смешивание с цветомtransparentс процентным значениемpt = 100% - p1 - p2.
- Если
Формальный синтаксис
<color-mix()> = color-mix( <color-interpolation-method> , [ <color> && <percentage [0,100]>? ]#{2}) <color-interpolation-method> = in [ <rectangular-color-space> | <polar-color-space> <hue-interpolation-method>? | <custom-color-space> ] <color> = <color-base> | currentColor | <system-color> | <light-dark()> | <deprecated-system-color> <rectangular-color-space> = srgb | srgb-linear | display-p3 | display-p3-linear | a98-rgb | prophoto-rgb | rec2020 | lab | oklab | xyz | xyz-d50 | xyz-d65 <polar-color-space> = hsl | hwb | lch | oklch <hue-interpolation-method> = [ shorter | longer | increasing | decreasing ] hue <custom-color-space> = <dashed-ident> <color-base> = <hex-color> | <color-function> | <named-color> | <color-mix()> | transparent <system-color> = AccentColor | AccentColorText | ActiveText | ButtonBorder | ButtonFace | ButtonText | Canvas | CanvasText | Field | FieldText | GrayText | Highlight | HighlightText | LinkText | Mark | MarkText | SelectedItem | SelectedItemText | VisitedText <light-dark()> = light-dark( <color>, <color> ) <deprecated-system-color> = ActiveBorder | ActiveCaption | AppWorkspace | Background | ButtonHighlight | ButtonShadow | CaptionText | InactiveBorder | InactiveCaption | InactiveCaptionText | InfoBackground | InfoText | Menu | MenuText | Scrollbar | ThreeDDarkShadow | ThreeDFace | ThreeDHighlight | ThreeDLightShadow | ThreeDShadow | Window | WindowFrame | WindowText <color-function> = <rgb()> | <rgba()> | <hsl()> | <hsla()> | <hwb()> | <lab()> | <lch()> | <oklab()> | <oklch()> | <color()> <named-color> = aliceblue | antiquewhite | aqua | aquamarine | azure | beige | bisque | black | blanchedalmond | blue | blueviolet | brown | burlywood | cadetblue | chartreuse | chocolate | coral | cornflowerblue | cornsilk | crimson | cyan | darkblue | darkcyan | darkgoldenrod | darkgray | darkgreen | darkgrey | darkkhaki | darkmagenta | darkolivegreen | darkorange | darkorchid | darkred | darksalmon | darkseagreen | darkslateblue | darkslategray | darkslategrey | darkturquoise | darkviolet | deeppink | deepskyblue | dimgray | dimgrey | dodgerblue | firebrick | floralwhite | forestgreen | fuchsia | gainsboro | ghostwhite | gold | goldenrod | gray | green | greenyellow | grey | honeydew | hotpink | indianred | indigo | ivory | khaki | lavender | lavenderblush | lawngreen | lemonchiffon | lightblue | lightcoral | lightcyan | lightgoldenrodyellow | lightgray | lightgreen | lightgrey | lightpink | lightsalmon | lightseagreen | lightskyblue | lightslategray | lightslategrey | lightsteelblue | lightyellow | lime | limegreen | linen | magenta | maroon | mediumaquamarine | mediumblue | mediumorchid | mediumpurple | mediumseagreen | mediumslateblue | mediumspringgreen | mediumturquoise | mediumvioletred | midnightblue | mintcream | mistyrose | moccasin | navajowhite | navy | oldlace | olive | olivedrab | orange | orangered | orchid | palegoldenrod | palegreen | paleturquoise | palevioletred | papayawhip | peachpuff | peru | pink | plum | powderblue | purple | rebeccapurple | red | rosybrown | royalblue | saddlebrown | salmon | sandybrown | seagreen | seashell | sienna | silver | skyblue | slateblue | slategray | slategrey | snow | springgreen | steelblue | tan | teal | thistle | tomato | turquoise | violet | wheat | white | whitesmoke | yellow | yellowgreen <color-mix()> = color-mix( <color-interpolation-method> , [ <color> && <percentage [0,100]>? ]#{2}) <rgb()> = rgb( <percentage>#{3} , <alpha-value>? ) | rgb( <number>#{3} , <alpha-value>? ) | rgb( [ <number> | <percentage> | none ]{3} [ / [ <alpha-value> | none ] ]? ) <rgba()> = rgba( <percentage>#{3} , <alpha-value>? ) | rgba( <number>#{3} , <alpha-value>? ) | rgba( [ <number> | <percentage> | none ]{3} [ / [ <alpha-value> | none ] ]? ) <hsl()> = hsl( <hue>, <percentage>, <percentage>, <alpha-value>? ) | hsl( [ <hue> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? ) <hsla()> = hsla( <hue>, <percentage>, <percentage>, <alpha-value>? ) | hsla( [ <hue> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? ) <hwb()> = hwb( [ <hue> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? ) <lab()> = lab( [<percentage> | <number> | none] [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ / [<alpha-value> | none] ]? ) <lch()> = lch( [<percentage> | <number> | none] [ <percentage> | <number> | none] [ <hue> | none] [ / [<alpha-value> | none] ]? ) <oklab()> = oklab( [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ / [<alpha-value> | none] ]? ) <oklch()> = oklch( [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ <hue> | none] [ / [<alpha-value> | none] ]? ) <color()> = color( [ from <color> ]? <colorspace-params> [ / [ <alpha-value> | none ] ]? ) <alpha-value> = <number> | <percentage> <hue> = <number> | <angle> <colorspace-params> = [<custom-params> | <predefined-rgb-params> | <xyz-params>] <custom-params> = <dashed-ident> [ <number> | <percentage> | none ]+ <predefined-rgb-params> = <predefined-rgb> [ <number> | <percentage> | none ]{3} <xyz-params> = <xyz> [ <number> | <percentage> | none ]{3} <predefined-rgb> = srgb | srgb-linear | display-p3 | display-p3-linear | a98-rgb | prophoto-rgb | rec2020 <xyz> = xyz | xyz-d50 | xyz-d65
Примеры
Смешивание двух цветов
В этом примере показано смешивание двух цветов: красного #a71e14 с разными процентными значениями и белого без указанного процентного значения. Чем выше процентное значение #a71e14, тем больше красного и меньше белого будет в результирующем цвете.
HTML
<ul> <li>0%</li> <li>25%</li> <li>50%</li> <li>75%</li> <li>100%</li> <li></li> </ul>
CSS
Функция color-mix() используется для постепенного увеличения процентного содержания красного вплоть до 100%. В шестом элементе <li> процентное значение не указано ни для одного из цветов.
ul {
display: flex;
list-style-type: none;
font-size: 150%;
gap: 10px;
border: 2px solid;
padding: 10px;
}
li {
padding: 10px;
flex: 1;
box-sizing: border-box;
font-family: monospace;
outline: 3px solid #a71e14;
text-align: center;
}
li:nth-child(1) {
background-color: color-mix(in oklab, #a71e14 0%, white);
}
li:nth-child(2) {
background-color: color-mix(in oklab, #a71e14 25%, white);
}
li:nth-child(3) {
background-color: color-mix(in oklab, #a71e14 50%, white);
}
li:nth-child(4) {
background-color: color-mix(in oklab, #a71e14 75%, white);
}
li:nth-child(5) {
background-color: color-mix(in oklab, #a71e14 100%, white);
}
li:nth-child(6) {
background-color: color-mix(in oklab, #a71e14, white);
}
Результат
Суммарное значение обоих цветов в функции color-mix() составляет 100%, даже если заданные разработчиком значения в сумме не дают 100%. В этом примере процентное значение задано только для одного цвета, поэтому для другого неявно устанавливается такое значение, чтобы их сумма составляла 100%. В последнем элементе <li>, где процентное значение не указано ни для одного цвета, для обоих по умолчанию используется 50%.
Смешивание списка цветов
В этом примере показана передача списка цветов в качестве аргумента функции color-mix(). Функция принимает любое количество цветов, а не только два; для каждого из них можно при необходимости указать процентное значение.
HTML
<ul> <li>1 color</li> <li>3 colors, with percentages</li> <li>4 colors, no percentages</li> </ul>
CSS
Первый элемент <li> смешивает один цвет, поэтому результатом будет этот же цвет. Во втором смешиваются три цвета, процентные значения которых в сумме составляют 100%. В третьем смешиваются четыре цвета без указанных процентных значений, поэтому каждому достаётся равная доля.
ul {
display: flex;
list-style-type: none;
font-size: 150%;
gap: 10px;
border: 2px solid;
padding: 10px;
}
li {
padding: 10px;
flex: 1;
box-sizing: border-box;
font-family: monospace;
text-align: center;
}
li:nth-child(1) {
background-color: color-mix(in oklab, teal);
}
li:nth-child(2) {
background-color: color-mix(in oklab, teal 20%, olive 30%, blue 50%);
}
li:nth-child(3) {
background-color: color-mix(in oklab, teal, olive, blue, purple);
}
@supports not (color: color-mix(in oklab, red, white, blue)) {
body::before {
content: "Your browser doesn't support color lists in the color-mix() function.";
background-color: wheat;
display: block;
text-align: center;
padding: 1rem 0;
}
}
Результат
Добавление прозрачности
В этом примере показано использование функции color-mix() для добавления прозрачности к цвету путём смешивания любого цвета с transparent.
HTML
<ul> <li>0%</li> <li>25%</li> <li>50%</li> <li>75%</li> <li>100%</li> <li></li> </ul>
CSS
Функция color-mix() используется для постепенного увеличения процентного содержания red, заданного с помощью пользовательского свойства с именем --base, объявленного для :root. В шестом элементе <li> процентное значение не указано, поэтому результирующий цвет становится вдвое прозрачнее цвета --base. Чтобы прозрачность была видна, для <ul> задан полосатый фон.
ul {
display: flex;
list-style-type: none;
font-size: 150%;
gap: 10px;
border: 2px solid;
padding: 10px;
}
li {
padding: 10px;
flex: 1;
box-sizing: border-box;
font-family: monospace;
outline: 1px solid var(--base);
text-align: center;
}
:root {
--base: red;
}
ul {
background: repeating-linear-gradient(
45deg,
chocolate 0px 2px,
white 2px 12px
);
}
li:nth-child(1) {
background-color: color-mix(in srgb, var(--base) 0%, transparent);
}
li:nth-child(2) {
background-color: color-mix(in srgb, var(--base) 25%, transparent);
}
li:nth-child(3) {
background-color: color-mix(in srgb, var(--base) 50%, transparent);
}
li:nth-child(4) {
background-color: color-mix(in srgb, var(--base) 75%, transparent);
}
li:nth-child(5) {
background-color: color-mix(in srgb, var(--base) 100%, transparent);
}
li:nth-child(6) {
background-color: color-mix(in srgb, var(--base), transparent);
}
Результат
Таким образом, функцию color-mix() можно использовать для добавления прозрачности к любому цвету, даже если он уже частично прозрачен (значение альфа-канала меньше 1). Однако с помощью color-mix() нельзя сделать полупрозрачный цвет полностью непрозрачным. Для этого используйте относительный цвет с цветовой функцией CSS. Относительные цвета позволяют изменять значение любого цветового канала, в том числе увеличивать альфа-канал, чтобы сделать цвет полностью непрозрачным.
Использование интерполяции оттенка в color-mix()
В этом примере показаны доступные функции color-mix() методы интерполяции оттенка. При использовании интерполяции оттенка итоговый оттенок находится между значениями оттенка смешиваемых цветов. Результат будет отличаться в зависимости от выбранного направления движения по цветовому кругу.
Подробнее см. в разделе <hue-interpolation-method>.
<p>longer</p> <ul> <li>100%</li> <li>80%</li> <li>60%</li> <li>40%</li> <li>20%</li> <li>0%</li> </ul> <p>shorter</p> <ul> <li>100%</li> <li>80%</li> <li>60%</li> <li>40%</li> <li>20%</li> <li>0%</li> </ul> <p>increasing</p> <ul> <li>100%</li> <li>80%</li> <li>60%</li> <li>40%</li> <li>20%</li> <li>0%</li> </ul> <p>decreasing</p> <ul> <li>100%</li> <li>80%</li> <li>60%</li> <li>40%</li> <li>20%</li> <li>0%</li> </ul>
CSS
Метод интерполяции shorter hue проходит по короткому пути вокруг цветового круга, а метод longer hue — по длинному. При использовании increasing hue путь начинается с увеличения значений. При использовании decreasing hue значение уменьшается. Мы смешиваем два значения <named-color>, чтобы создать последовательность промежуточных цветов lch(), различающихся в зависимости от выбранного направления движения по цветовому кругу. Среди смешанных цветов есть red, blue и yellow со значениями оттенка LCH приблизительно 41deg, 301deg и 100deg соответственно.
Чтобы избежать дублирования кода, для обоих цветов и метода интерполяции мы использовали пользовательские свойства CSS, задавая разные значения для каждого элемента <ul>.
body {
font-family: monospace;
}
ul {
display: flex;
list-style-type: none;
font-size: 150%;
gap: 10px;
padding: 10px;
margin: 0;
}
li {
padding: 10px;
flex: 1;
outline: 1px solid var(--base);
text-align: center;
}
ul:nth-of-type(1) {
--distance: longer; /* 52 degree hue increments */
--base: red;
--mixin: blue;
}
ul:nth-of-type(2) {
/* 20 degree hue decrements */
--distance: shorter;
--base: red;
--mixin: blue;
}
ul:nth-of-type(3) {
/* 40 degree hue increments */
--distance: increasing;
--base: yellow;
--mixin: blue;
}
ul:nth-of-type(4) {
/* 32 degree hue decrements */
--distance: decreasing;
--base: yellow;
--mixin: blue;
}
li:nth-child(1) {
background-color: color-mix(
in lch var(--distance) hue,
var(--base) 100%,
var(--mixin)
);
}
li:nth-child(2) {
background-color: color-mix(
in lch var(--distance) hue,
var(--base) 80%,
var(--mixin)
);
}
li:nth-child(3) {
background-color: color-mix(
in lch var(--distance) hue,
var(--base) 60%,
var(--mixin)
);
}
li:nth-child(4) {
background-color: color-mix(
in lch var(--distance) hue,
var(--base) 40%,
var(--mixin)
);
}
li:nth-child(5) {
background-color: color-mix(
in lch var(--distance) hue,
var(--base) 20%,
var(--mixin)
);
}
li:nth-child(6) {
background-color: color-mix(
in lch var(--distance) hue,
var(--base) 0%,
var(--mixin)
);
}
Результат
При использовании longer hue приращения или уменьшения значений между цветами всегда будут такими же или большими, чем при использовании shorter hue. Используйте increasing hue или decreasing hue, если направление изменения значения оттенка важнее расстояния между значениями.
Спецификации
| Спецификация |
|---|
| Модуль CSS Color уровня 5 # color-mix |
Совместимость с браузерами
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome для Android | Firefox для Android | Opera для Android | Safari для iOS | Samsung Internet | WebView для Android | WebView для iOS | |
color-mix |
111 |
111 |
113 |
97 |
16.2 |
111 |
113 |
75 |
16.2 |
22.0 |
111 |
16.2 |
variadic_color_arguments |
Нет |
Нет |
150 |
Нет |
предварительная версия |
Нет |
150 |
Нет |
Нет |
Нет |
Нет |
Нет |
См. также
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/color_value/color-mix