Относительный синтаксис цвета в CSS: подробное объяснение
Если вы когда-либо определяли дюжину пользовательских свойств только для того, чтобы создать полупрозрачную версию цвета вашего бренда, вы уже понимаете проблему, которую решает относительный синтаксис цвета в CSS. Эта функция позволяет создавать новые цвета непосредственно из существующих внутри любой современной CSS-функции цвета — без препроцессоров, без JavaScript, без дополнительных переменных.
Ключевые моменты
- Относительный синтаксис цвета в CSS использует ключевое слово
fromдля создания новых цветов из существующего исходного цвета, предоставляя доступ к его отдельным каналам как к изменяемым переменным. - Он работает с функциями
rgb(),hsl(),hwb(),lab(),lch(),oklab()иoklch(). - OKLCH является предпочтительным цветовым пространством для манипуляций, поскольку его канал яркости перцептивно однороден, что обеспечивает визуально согласованные результаты для всех оттенков.
- Относительные цвета естественно интегрируются в системы дизайна на основе токенов, позволяя определить один базовый цвет и создать из него все варианты без препроцессоров или этапов сборки.
Что такое относительный синтаксис цвета в CSS?
Относительные цвета в CSS, определённые в спецификации CSS Color Level 5, позволяют взять существующий цвет — называемый исходным цветом (origin color) — и использовать его отдельные каналы в качестве переменных для построения нового цвета. Ключевым дополнением является ключевое слово from.
Вот базовая структура:
color-function(from <origin-color> channel1 channel2 channel3)
Когда браузер встречает from, он преобразует исходный цвет в целевое цветовое пространство, предоставляет каждый канал как именованную переменную и позволяет передавать эти переменные — изменённые или неизменённые — в качестве выходных значений.
Это работает со всеми современными CSS-функциями цвета, такими как rgb(), hsl(), hwb(), lab(), lch(), oklab() и oklch().
Как работает CSS-синтаксис цвета с from
Рассмотрим простой пример:
/* Origin color: green */
/* Channels exposed: r=0, g=128, b=0 */
color: rgb(from green r g b); /* outputs rgb(0 128 0) */
Здесь выходное значение идентично входному, но настоящая мощь заключается в том, что вы можете изменять отдельные каналы с помощью calc():
/* Rotate the hue by 180 degrees to get the complement */
background: hsl(from blue calc(h + 180) s l);
/* Lighten by multiplying the lightness channel */
background: oklch(from blue calc(l * 1.25) c h);
/* Reduce opacity without a separate variable */
background: rgb(from lime r g b / 50%);
Значения каналов преобразуются в простые числа внутри функции, поэтому арифметика calc() работает корректно без несоответствия единиц измерения.
Почему стоит использовать относительные цвета в OKLCH
Не все цветовые пространства одинаково подходят для манипуляций. HSL знаком многим, но его канал яркости не является перцептивно однородным — изменение l на одинаковую величину даёт визуально несогласованные результаты для разных оттенков.
OKLCH решает эту проблему. Его канал яркости перцептивно однороден, то есть сдвиг на +0.1 выглядит как одинаковый визуальный шаг независимо от оттенка. Это делает его отличным выбором для генерации оттенков, теней и доступных контрастных пар.
Если вы не знакомы с перцептивными цветовыми пространствами, цветовая модель OKLab/OKLCH, представленная Бьорном Оттоссоном, объясняет обоснование этих новых цветовых пространств.
/* Darken by 25% */
background: oklch(from var(--color-primary) calc(l * 0.75) c h);
/* Generate a high-contrast text color */
color: oklch(from var(--color-primary) calc(l + 0.6) c h);
Обратите внимание, что канал яркости в OKLCH имеет диапазон от 0 до 1, поэтому сдвиг calc(l + 0.6) является существенным. Значения, выходящие за допустимый диапазон, автоматически ограничиваются браузером.
Относительные цвета vs. color-mix()
Эти две CSS-функции для работы с цветом служат разным целям. color-mix() смешивает два цвета в заданном соотношении. Относительные цвета в CSS напрямую манипулируют каналами одного исходного цвета. Если вам нужно состояние наведения, приглушённый вариант или токен с изменённой прозрачностью, используйте относительный синтаксис. Если нужно интерполировать между двумя различными цветами, используйте color-mix().
Discover how at OpenReplay.com.
Интеграция в систему дизайна на основе токенов
Именно здесь относительные цвета в CSS действительно проявляют себя. Определите один базовый токен, а затем создайте из него все варианты:
:root {
--color-primary: #3b82f6;
--color-primary-hover: oklch(from var(--color-primary) calc(l * 0.9) c h);
--color-primary-active: oklch(from var(--color-primary) calc(l * 0.8) c h);
--color-primary-disabled: oklch(from var(--color-primary) l c h / 0.5);
--color-on-primary: oklch(from var(--color-primary) calc(l + 0.6) c h);
}
Измените --color-primary, и все производные токены обновятся автоматически. Никаких Sass-функций, никаких этапов сборки.
Поддержка браузерами
Относительный синтаксис цвета поддерживается в современных версиях Chromium, Firefox и Safari. Используйте @supports для безопасной проверки:
@supports (color: rgb(from white r g b)) {
/* relative color syntax is available */
}
Для браузеров без поддержки предоставьте резервный цвет перед объявлением относительного цвета. Каскад гарантирует, что старые браузеры используют статическое значение, а современные браузеры переопределяют его:
.button {
background: #3b82f6;
background: oklch(from var(--color-primary) calc(l * 0.9) c h);
}
Заключение
Относительный синтаксис цвета в CSS заменяет целую категорию логики препроцессоров одним читаемым паттерном. Выбирайте OKLCH для перцептивно согласованных корректировок яркости, используйте hsl(), когда нужен прямой контроль насыщенности, и связывайте всё с пользовательским свойством, чтобы вся ваша палитра оставалась синхронизированной из одного исходного токена.
Часто задаваемые вопросы
Да. Вы можете передать любое пользовательское свойство в качестве исходного цвета, используя var(). Например, oklch(from var(--brand-color) calc(l * 0.8) c h) работает как ожидается. Браузер сначала разрешает переменную, затем преобразует полученный цвет в целевое цветовое пространство и предоставляет доступ к его каналам.
Браузер автоматически ограничивает значения, выходящие за диапазон. Например, если выражение calc() выводит яркость OKLCH выше 1 или ниже 0, браузер обрезает её до допустимого диапазона. Это означает, что в большинстве случаев вам не нужно вручную защищаться от переполнения.
Влияние на производительность незначительно при типичном использовании. Браузер разрешает относительные цвета во время вычисления значений, аналогично тому, как он разрешает calc() в других свойствах. Вам потребуются тысячи объявлений относительных цветов на одной странице, прежде чем появится какая-либо измеримая разница.
Функции относительного цвета можно связывать в цепочку, если результат одного преобразования разрешается в допустимое значение цвета. На практике разработчики часто присваивают результат вычисления относительного цвета пользовательскому свойству и используют его в качестве исходного цвета для другого преобразования, что позволяет выполнять несколько шагов манипуляции цветом, сохраняя при этом читаемость кода.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.