CSS color-mix(): нативное смешивание цветов в браузере
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://colorfyi.com/iframe/entity//" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://colorfyi.com/entity//
Add a dynamic SVG badge to your README or docs.
[](https://colorfyi.com/entity//)
Use the native HTML custom element.
На протяжении лет генерация вариантов цвета в CSS требовала либо жёсткого задания каждого оттенка вручную, либо обращения к JavaScript и библиотеке работы с цветами вроде chroma.js или tinycolor2. Функция CSS color-mix() меняет это. Это нативная CSS-функция, теперь поддерживаемая всеми основными браузерами, которая смешивает два цвета в заданной пропорции — прямо в таблице стилей, без JavaScript и без препроцессинга.
Эта статья полностью охватывает синтаксис, объясняет, почему выбор цветового пространства меняет всё, рассматривает практические кейсы, делающие color-mix() действительно полезным, и касается поддержки браузеров и стратегий запасных вариантов.
Что такое color-mix()?
color-mix() — функция CSS Color Level 5, принимающая два значения цвета и пропорцию смешивания и возвращающая результирующий смешанный цвет. Это CSS-эквивалент смешивания двух красок, но с критическим дополнительным параметром: цветовым пространством, в котором происходит смешивание.
Простейший кейс — создание оттенков от базового цвета. Вместо определения каждого варианта оттенка фирменного синего вручную можно получать их динамически:
:root {
--brand-blue: #2563EB;
/* Осветления — смешиваем с белым */
--brand-blue-light: color-mix(in oklch, var(--brand-blue) 60%, white);
--brand-blue-lighter: color-mix(in oklch, var(--brand-blue) 30%, white);
/* Затемнения — смешиваем с чёрным */
--brand-blue-dark: color-mix(in oklch, var(--brand-blue) 80%, black);
--brand-blue-darker: color-mix(in oklch, var(--brand-blue) 50%, black);
}
Базовый синий #2563EB определяется один раз. Осветления и затемнения выводятся из него. При изменении фирменного цвета все варианты обновляются автоматически.
Синтаксис и параметры
Полный синтаксис color-mix():
color-mix(in <color-space>, <color1> [<percentage>]?, <color2> [<percentage>]?)
Параметр цветового пространства
Первый аргумент, in <color-space>, обязателен и задаёт место, где происходит смешивание. Допустимые варианты:
srgb— смешивание в стандартном RGB (наиболее знакомый, но склонный к тусклым средним точкам)hsl— смешивание вдоль цилиндра HSLhwb— смешивание в HWB (Оттенок, Белизна, Чернота)lab— смешивание в CIE Lab (перцептуально равномерный)oklab— смешивание в Oklab (лучшая равномерность, чем у CIE Lab)lch— смешивание в LCH (цилиндрический CIE Lab)oklch— смешивание в OKLCH (цилиндрический Oklab, рекомендуется для большинства задач)display-p3— смешивание в широкой гамме Display P3xyz— смешивание в CIE XYZ
Для большинства дизайнерской работы oklch даёт наиболее перцептуально естественные результаты. Подробнее об этом — в следующем разделе.
Аргументы цвета
Два значения цвета могут быть любым допустимым CSS-цветом: HEX-коды, rgb(), hsl(), oklch(), именованные цвета или пользовательские свойства CSS. Каждый может опционально иметь процентное значение, указывающее, насколько этот цвет вносит вклад в смесь:
/* Смешивание 50/50 (по умолчанию, если проценты не указаны) */
color-mix(in oklch, #FF5733, #3498DB)
/* 70% первого цвета, 30% второго */
color-mix(in oklch, #FF5733 70%, #3498DB 30%)
/* 80% первого цвета — процент второго выводится как 20% */
color-mix(in oklch, #FF5733 80%, #3498DB)
Если проценты суммируются менее 100%, результат частично прозрачен. Если они превышают 100%, проценты нормализуются. Если ни один процент не указан, смешивание 50/50.
/* Они эквивалентны */
color-mix(in srgb, blue, red)
color-mix(in srgb, blue 50%, red 50%)
color-mix(in srgb, blue 50%, red)
Смешивание в разных цветовых пространствах
Выбор цветового пространства не косметический — он фундаментально меняет производимый цвет. Те же два цвета, смешанные в разных пространствах, дают кардинально разные результаты.
Смешивание в sRGB
Смешивание в sRGB работает путём линейной интерполяции каналов красного, зелёного и синего. Для многих пар цветов это даёт приемлемые результаты, но дополнительные цвета (находящиеся на противоположных сторонах цветового круга) часто дают десатурированную, сероватую среднюю точку.
/* Смешивание оранжево-красного и синего в sRGB */
color-mix(in srgb, #FF5733 50%, #3498DB 50%)
/* Результат: приглушённый, несколько коричневатый фиолетовый — диапазон [#9A77B7] */
Проблема в том, что RGB-каналы дополнительных цветов компенсируют друг друга при усреднении. Красный [255, 87, 51] и Синий [52, 152, 219] дают среднюю точку [154, 120, 135] — десатурированный, «замутнённый» результат.
Смешивание в HSL
Смешивание в HSL интерполирует вдоль цветового круга, что может вызвать другую проблему: вращение оттенка через неожиданные промежуточные цвета.
/* Оранжевый (оттенок ~15°) смешан с синим (оттенок ~210°) в HSL */
color-mix(in hsl, #FF5733 50%, #3498DB 50%)
/* Оттенок интерполируется через ~112° — получается зеленоватый промежуточный */
Когда два цвета далеко друг от друга на цветовом круге, кратчайший путь между ними в HSL может проходить через зелёный или другие неожиданные оттенки. HSL также разделяет проблему перцептуальной неравномерности hsl() в целом — средняя точка светлоты может не выглядеть как середина между двумя исходными светлотами.
Смешивание в OKLCH
Смешивание в OKLCH является рекомендуемым подходом для большинства практических задач. Оно интерполирует в перцептуально равномерном пространстве, что означает, что промежуточные цвета выглядят как естественные визуальные середины — яркие, сбалансированные, без неожиданного смещения оттенка.
/* Оранжево-красный смешан с синим в OKLCH */
color-mix(in oklch, #FF5733 50%, #3498DB 50%)
/* Результат: яркий пурпурно-сиреневый — перцептуально посередине */
#FF5733 (тёплый оранжево-красный) и #3498DB (яркий синий), смешанные 50/50 в OKLCH, дают насыщенный промежуточный. Оттенок интерполирует прямо через фиолетовый диапазон — именно то, чего ожидает дизайнер, когда его просят «найти среднее» между оранжевым и синим.
Смешивание в Oklab (кратчайший/длиннейший путь оттенка)
Для интерполяции оттенка можно также указать, следовать ли по более короткой или длинной дуге вокруг цветового круга:
/* Кратчайший путь оттенка (по умолчанию) */
color-mix(in oklch shorter hue, red, blue)
/* Длиннейший путь оттенка — идёт в другую сторону вокруг круга */
color-mix(in oklch longer hue, red, blue)
/* Возрастающий оттенок */
color-mix(in oklch increasing hue, red, blue)
Этот контроль полезен, когда намеренно нужна интерполяция, проходящая через определённые промежуточные оттенки — например, градиент, идущий от красного через жёлтый к синему, а не через фиолетовый.
Таблица сравнения
| Цветовое пространство | Середина оранжевый + синий | Визуальный характер |
|---|---|---|
srgb |
Приглушённый сероватый фиолетовый | Десатурированный, мутный |
hsl |
Зеленоватый | Неожиданный сдвиг оттенка |
lab |
Фиолетовый, менее яркий | Естественнее, чем sRGB |
oklch |
Яркий пурпурно-сиреневый | Наиболее перцептуально естественный |
Используйте конвертер цветов для изучения OKLCH-значений ваших конкретных цветов и предсказания того, как они будут смешиваться.
Практические кейсы
Создание состояний наведения и нажатия
Одно из наиболее немедленно полезных применений — генерация интерактивных состояний без определения отдельных переменных для каждого:
:root {
--btn-bg: oklch(0.55 0.22 250); /* Ваш фирменный синий */
}
.btn {
background-color: var(--btn-bg);
}
.btn:hover {
/* Затемнить на 15%, смешивая с чёрным */
background-color: color-mix(in oklch, var(--btn-bg) 85%, black);
}
.btn:active {
/* Затемнить больше для нажатого состояния */
background-color: color-mix(in oklch, var(--btn-bg) 70%, black);
}
.btn:disabled {
/* Десатурировать и осветлить для отключённого */
background-color: color-mix(in oklch, var(--btn-bg) 40%, white);
opacity: 0.6;
}
Это устраняет необходимость выбирать три отдельных оттенка в дизайн-инструменте и жёстко их задавать. Цвета наведения и нажатия математически выводятся из базового, сохраняя согласованность отношений даже при смене фирменного цвета.
Создание семантических цветовых шкал
Системы дизайна нуждаются в семантических цветах — успех, предупреждение, опасность — гармонирующих с фирменной палитрой. color-mix() позволяет получать их из фирменного цвета, а не выбирать независимо:
:root {
--brand: oklch(0.55 0.22 250); /* Фирменный синий */
/* Успех: смешиваем бренд с чистым зелёным, сохраняя намёк на идентичность бренда */
--success: color-mix(in oklch, oklch(0.65 0.22 145) 85%, var(--brand) 15%);
/* Предупреждение: чистый янтарь — без смешивания */
--warning: oklch(0.75 0.18 70);
/* Опасность: чистый красный */
--danger: oklch(0.62 0.24 25);
/* Тонированные фоны для каждого состояния */
--success-bg: color-mix(in oklch, var(--success) 12%, white);
--warning-bg: color-mix(in oklch, var(--warning) 12%, white);
--danger-bg: color-mix(in oklch, var(--danger) 12%, white);
}
--success-bg — очень светлый оттенок зелёного успеха, выведенный автоматически. Используйте их для баннеров уведомлений, окон оповещений и состояний ошибок полей форм.
Динамическая генерация полных шкал оттенков
Хотя Генератор оттенков — правильный инструмент для создания полной шкалы 50–950 с точными перцептуальными шагами, color-mix() может генерировать пригодное приближение в строках кода для компонентов, нуждающихся в нескольких вариантах:
:root {
--primary: oklch(0.58 0.20 250);
--primary-50: color-mix(in oklch, var(--primary) 8%, white);
--primary-100: color-mix(in oklch, var(--primary) 15%, white);
--primary-200: color-mix(in oklch, var(--primary) 30%, white);
--primary-300: color-mix(in oklch, var(--primary) 50%, white);
--primary-400: color-mix(in oklch, var(--primary) 70%, white);
--primary-500: var(--primary);
--primary-600: color-mix(in oklch, var(--primary) 85%, black);
--primary-700: color-mix(in oklch, var(--primary) 70%, black);
--primary-800: color-mix(in oklch, var(--primary) 55%, black);
--primary-900: color-mix(in oklch, var(--primary) 35%, black);
--primary-950: color-mix(in oklch, var(--primary) 20%, black);
}
Получение цветов тёмного режима
color-mix() особенно ценен для систематического получения цветов поверхностей в тёмном режиме:
@media (prefers-color-scheme: dark) {
:root {
--surface-base: #09090b;
--surface-elevated: color-mix(in oklch, var(--brand) 8%, #09090b);
--surface-overlay: color-mix(in oklch, var(--brand) 12%, #09090b);
}
}
Смешивание небольшого количества фирменного цвета в тёмные поверхности создаёт тонкий оттенок — техника, используемая macOS от Apple и многими современными системами дизайна, чтобы тёмный режим ощущался менее стерильным, чем чисто нейтральные поверхности.
Поведение альфа-канала
Когда проценты не суммируются до 100%, результат частично прозрачен. Это можно использовать намеренно для создания полупрозрачных вариантов:
/* 30% синего на прозрачной основе — эквивалент rgba при 30% прозрачности */
color-mix(in srgb, blue 30%, transparent)
/* Также допустимо: именованная прозрачность с другой стороны */
color-mix(in oklch, #3B82F6 25%, transparent)
Это заменяет паттерн использования rgba() с фиксированным альфа. Преимущество в том, что отношение прозрачности явно выражено в проценте смешивания, и можно смешивать с любым цветом — а не только с чистой прозрачностью.
Поддержка браузеров и запасные варианты
По состоянию на 2026 год color-mix() полностью поддерживается в:
- Chrome/Edge: с версии 111 (март 2023)
- Firefox: с версии 113 (май 2023)
- Safari: с версии 16.2 (декабрь 2022)
Глобальная поддержка превышает 90%. Пользователи, не видящие результаты color-mix(), — это те, кто работает с очень старыми мобильными браузерами или в корпоративных средах с заблокированными версиями браузеров.
Запасной вариант с прогрессивным улучшением
Объявления пользовательских свойств CSS каскадируются. Если браузер не поддерживает color-mix(), используется запасной вариант из предыдущей строки:
:root {
/* Запасной вариант для браузеров без color-mix() */
--btn-hover: #1D4ED8;
/* Переопределение с вычисленным значением для современных браузеров */
--btn-hover: color-mix(in oklch, var(--btn-bg) 85%, black);
}
Поскольку пользовательские свойства повторно объявляют одну и ту же переменную, это работает как паттерн прогрессивного улучшения. Браузеры без поддержки color-mix() используют явный запасной цвет; современные браузеры используют выведенное значение.
Альтернативно используйте @supports:
.btn:hover {
background-color: #1D4ED8; /* Запасной вариант */
}
@supports (color: color-mix(in oklch, red, blue)) {
.btn:hover {
background-color: color-mix(in oklch, var(--btn-bg) 85%, black);
}
}
Подход @supports более явный и его проще убрать, когда вы в конечном счёте откажетесь от поддержки старых браузеров.
Ключевые выводы
color-mix()смешивает два цвета нативно в CSS, устраняя для многих кейсов необходимость в JavaScript или предварительно сгенерированных таблицах оттенков.- Аргумент
in <color-space>управляет местом смешивания и кардинально влияет на результат. Используйтеoklchдля большинства работ — он даёт перцептуально естественные средние точки без мутной десатурации (проблема sRGB) и неожиданных смещений оттенка (проблема HSL). - Наиболее практичные кейсы: интерактивные состояния (наведение, нажатие, отключение), получение семантических цветов, тонирование поверхностей тёмного режима и генерация небольших шкал оттенков из одной базовой переменной.
- Когда проценты суммируются менее 100%, результат частично прозрачен — полезно для создания вариантов прозрачности без
rgba(). - Поддержка браузеров охватывает все современные браузеры с начала 2023 года. Предоставьте жёстко заданный запасной вариант в предшествующем CSS-объявлении или внутри блока
@supportsдля старых сред. - Используйте конвертер цветов для перевода существующих фирменных цветов в OKLCH перед использованием в
color-mix(), а генератор палитр для просмотра гармоничных цветовых отношений перед написанием CSS.