Руководство по современным цветам CSS с RGB, HSL, HWB, LAB и LCH
В интернете больше возможностей для раскрашивания, чем кажется на первый взгляд, и скоро всё станет ещё интереснее! Сегодня мы рассмотрим, как лучше всего использовать цвета в дизайн-системе, и что мы можем ожидать от наших цветов в недалёком будущем.
Хорошо известные значения цвета
Есть много разных способов определения цветов в CSS. Именованные цвета CSS — один из самых простых способов раскрасить элемент:
.my-element {
background-color: red;
}
Их очень мало, и они редко подходят для проектов, которые мы создаём! Мы также можем использовать шестнадцатеричное значение цвета. Этот код придаёт нашему элементу красный цвет фона:
.my-element {
background-color: #ff0000;
}
Если вы не специалист по цвету, то шестнадцатеричное значение очень трудно читать. Маловероятно, что вы сможете угадать цвет элемента, прочитав шестнадцатеричное значение. При создании веб-сайта дизайнер может дать нам шестнадцатеричное значение цвета, но если бы он попросил нас сделать его, скажем, на 20% темнее, мы потратили бы много времени на подбор шестнадцатеричного значения без визуального руководства или цветоподборщика.
RGB
RGB (Red/красный, Green/зелёный, Blue/синий) — это альтернативный способ записи цветов, который даёт нам доступ к тому же диапазону цветов, что и шестнадцатеричное представление цвета, но в гораздо более удобочитаемой форме. Для этого в CSS есть функция rgb()
. Цвета складываются: чем выше доля красного, зелёного и синего, тем светлее будет полученный цвет. Если мы используем только красный канал, результат будет красным:
.my-element {
background-color: rgb(255, 0, 0);
}
Установка максимального значения красного, зелёного и синего каналов приведёт к появлению белого цвета:
.my-element {
background-color: rgb(255, 255, 255);
}
Так же, мы можем добавить альфа-канал (для прозрачности) с помощью функции rgba()
:
.my-element {
background-color: rgba(255, 0, 0, 0.5); // прозрачность 50%
}
.my-element {
background-color: rgba(255, 0, 0, 1); // полностью не прозрачный
}
rgb()
и rgba()
позволяют нам до некоторой степени «смешивать» цвета в нашем коде, но результаты могут быть несколько непредсказуемыми.
HSL
Совсем недавно мы смогли начать использовать HSL(Hue/оттенок, Saturation/насыщенность, Lightness/яркость) с функциями цвета hsl()
и hsla()
. Для разработчика они гораздо более интуитивно понятны, когда дело доходит до настройки значений цвета. Например, мы можем получить более тёмные или более светлые варианты одного и того же цвета, настроив параметр яркости
/lightness
:
.my-element {
background-color: hsl(0deg, 100%, 20%); // тёмно-красный
}
.my-element {
background-color: hsl(0deg, 100%, 50%); // средний красный
}
.my-element {
background-color: hsl(0deg, 100%, 80%); // светло-красный
}
Параметр hue
/оттенок
представляет положение на цветовом круге и может принимать любое значение от 0
до 360deg
. Функция также принимает единицы поворота (например 0.5turn
) и безразмерные значения.
Все следующие значения действительны:
.my-element {
background-color: hsl(180deg, 50%, 50%);
}
.my-element {
background-color: hsl(0.5turn, 50%, 50%);
}
.my-element {
background-color: hsl(180, 50%, 50%);
}
Как мы вскоре увидим, hsl()
и hsla()
хорошо поддаются манипуляциям с пользовательскими свойствами.
currentColor
Ключевое слово currentColor
заслуживает упоминания, как ещё один способ установки цвета для элемента, который существует уже некоторое время. Оно позволяет нам эффективно использовать текущий цвет текста в качестве переменной. Он довольно ограничен по сравнению с настраиваемыми свойствами, но часто используется для установки цвета заливки SVG иконок, что бы они соответствовали цвету текста их родительского элемента. Об этом можно прочитать здесь: «Cascading SVG Fill Color»
Современный цветовой синтаксис
CSS Color Module Level 4 предоставляет нам более удобный синтаксис для наших цветовых функций, который широко поддерживается в браузерах. На больше не нужно разделять значения запятыми, а функции rgb()
и hsl()
могут принимать необязательный альфа-параметр, отделённый обратным слэшем '/':
.my-element {
/* Опциональное значение альфа устанавливает 50% непрозрачности */
background-color: hsl(0 100% 50% / 0.5);
}
.my-element {
/* Без указания значения альфа, фон полностью непрозрачный*/
background-color: hsl(0 100% 50%);
}
Новые цветовые функции CSS
HWB
HWB означает Hue/оттенок, Whiteness/белизна and Blackness/чернота. Как и HSL, hue
/оттенок
, может быть любым в диапазоне от 0 до 360. Два других аргумента контролируют, сколько белого или чёрного смешивать с этим оттенком, вплоть до 100% (что приведёт к полностью белому или чёрному цвету). Если смешивать равное количество белого и чёрного, цвет становится серым. Это можно рассматривать, как смешивание красок, что может быть особенно полезным для создания монохромных цветовых палитр.
LAB
LAB
и LCH
определены в спецификации, как независимые от устройства цвета. LAB
— это цветовое пространство, доступное в программном обеспечении, таком как Photoshop, и оно рекомендуется, если вы хотите, что бы цвет на экране выглядел, так же как, скажем, цвет напечатанный на футболке. Он использует три оси: яркости
, a-axis
/ось А
(от зелёного к красному) и b-axis
/ось Б
(от синего к жёлтому).
Яркость выражается в процентах, как и в HSL, но на самом деле она может превышать 100% при использовании функции lab()
. Очень яркие белые цвета могут использовать процентное содержание до 400%. Значения осей А и Б могут варьироваться от положительных до отрицательных. Два отрицательных значения сместят цвет в сторону зелёного/синего конца спектра, а положительные значения дадут более оранжевый/красный оттенок.
.my-element {
background-color: lab(80% 100 50); // красновато-розовый
}
.my-element {
background-color: lab(80% -80 -100); // синий/бирюзовый
}
LCH
LCH означает Lightness/яркость, Chroma/цветность, and Hue/оттенок. Как и в случае с LAB, яркость может быть более 100%. Подобно HSL, оттенок может быть в диапазоне от 0 до 360. Цветность представляет собой количество цвета, и мы можем воспринимать это как насыщенность в HSL. Но цветность может превышать 100% — на самом деле, теоретически она не ограничена. Пример использования:
.my-element {
background-color: lch(80% 100 50);
}
.my-element {
background-color: lch(80% 240 50); // этот цвет был бы за пределами отображаемого диапазона цветов современных браузеров
}
Однако существует ограничение на то, сколько цветов браузеры и мониторы могут отображать сегодня (подробнее об этом чуть позже), поэтому значение выше 230 вряд ли будут иметь значение — Цветность снижается, пока не окажется в пределах отображаемого диапазона.
Зачем нужны LAB и LCH, когда у нас есть HSL? Одна из причин заключается в том, что использование LAB или LCH даёт нам доступ к гораздо большему диапазону цветов. LCH и LAB созданы, что бы дать нам доступ ко всему спектру человеческого зрения. Кроме того, у HSL и RGB есть несколько недостатков: они не являются однородными по восприятию, а в HSL увеличение или уменьшение яркость имеет совершенно разный эффект в зависимости от оттенка.
В этой демонстрации мы можем увидеть резкий контраст между LCH и HSL, нажав переключатель оттенков серого Grayscale: Off/On
. Для полос оттенка и насыщенности HSL есть явные различия в восприятии яркости каждого квадрата, хотя компонент «яркость» функции HSL один и тот же. Между тем, полосы цветности и оттенка на стороне LCH имеют почти одинаково воспринимаемую яркость.
Мы также можем увидеть большую разницу при использовании LCH цветов для градиента. Оба градиента начинаются и заканчиваются одним и тем же цветом (со значениями LCH, преобразованными в эквиваленты HSL с помощью этого конвертора)
Возможно, LAB и LCH синтаксически несколько менее интуитивно понятны, но они лучше адаптированы для восприятия человеческого глаза. В статье «LCH colors in CSS: what, why, and how?» Леа Веру (Lea Verou) подробно объясняются преимущества LCH цвета. Она также создала подборщик цветов LCH.
Как и другие цветовые функции hwb()
, lsb()
и lch()
также могут принимать необязательный альфа параметр, отвечающий за непрозрачность.
.my-element {
background-color: lch(80% 240 50 / 0.5); // Полученный цвет имеет 50% непрозрачность
}
Поддержка браузером и цветовые пространства
В настоящее время hwb()
, lab()
и lch()
поддерживаются только Safari. Их можно сразу начинать использовать, предоставив запасной вариант для браузеров, не поддерживающих их. Браузеры, не поддерживающие цветовую функцию просто проигнорируют первое правило:
.my-element {
background-color: lch(55% 102 360);
/* LCH цвет конвертированный в RGB с конвертом Леа Веру: https://css.land/lch/ */
background-color: rgb(98.38% 0% 53.33%);
}
Если другие стили зависят от поддержки используемых цветовых функций, мы можем использовать запрос поддерживаемости свойства браузером:
.my-element {
display: none;
}
/* Этот элемент отобразится только если браузер поддерживает lch() */
@supports (background-color: lch(55% 102 360)) {
.my-element {
display: block;
background-color: lch(55% 102 360);
}
}
Стоит отметить, как Леа объясняет в своей статье, что хотя современные мониторы способны отображать цвета за пределами цветового пространства RGB, в настоящее время большинство браузеров поддерживают цвета только в цветовом пространстве sRGB. В демонстрации цветов LAB, вы можете заметить, что перемещение ползунка за определённую точку фактически не влияет на цвет, даже в Safari, где поддерживаются lab()
и lch()
. Использование значений цветов за пределами sRGB будет иметь эффект только при достаточном развитии оборудования и браузеров.
Теперь Safari поддерживает функцию color()
, которая позволяет отображать цвета в цветовом пространстве P3, но на данный момент они ограничены цветами RGB и ещё не дают всех преимуществ LAB и LCH.
.my-element {
background: rgb(98.38% 0% 53.33%); // bright pink
background: color(display-p3 0.947 0 0.5295); // equivalent in P3 color space
}
Рекомендуется прочитать: "Wide Gamut Color in CSS with Display-P3" Никиты Васильева
Доступность
Когда они получат широкую поддержку, возможно, LAB и LCH помогут нам выбрать более доступные цветовые комбинации. У текста должен быть одинаковый коэффициент контрастности с цветами фона, с разными значениями оттенка и цветности, если их значение яркости остаётся неизменным. В настоящее время с цветами HSL дело обстоит иначе.
Управление цветом
Более широкий спектр цветовых функций означает, что у нас больше возможностей для управления цветами в нашем приложении. Часто нам требуется несколько вариантов одного цвета в дизайн-системе, от тёмного до светлого.
Пользовательские свойства
Пользовательские свойства CSS или переменные CSS позволяют сохранить значения для повторного использования в таблицах стилей. Поскольку они допускают частичные значения свойств, они могут быть полезны для управления и манипуляций значениями цвета. HSL хорошо подходит для настраиваемых свойств, благодаря своей интуитивности. В предыдущей демонстрации я использую их для настройки оттенка каждого сегмента цветовой полосы, вычисляя значение --hue
на основе индекса элемента (определённого другой переменной)
li {
--hue: calc(var(--i) * (360 / 10));
background: hsl(var(--hue, 0) 50% 45%);
}
Мы также можем вычислять комплиментарные цвета (цвета с противоположных сторон цветового круга). Об этом много написано, поэтому не будем останавливаться на этой теме, но если вам интересно, тот статья Сары Суейдан (Sara Soueidan) об управлении цветом с помощью HSL многое вам объяснит.
Миграция с RGB на HSL
RGB цвет могут удовлетворять ваши потребности до определённого степени, но если вам нужна гибкость, что бы иметь возможность получения новых оттенков базовой палитры, возможно, вам следует переключиться на HSL (или LCH, когда он будет повсеместно поддерживаться). Я бы рекомендовал использовать его с CSS переменными.
Возможно вы храните цвета в переменных sass
:
$primary: rgb(141 66 245);
При преобразовании в HSL мы можем назначить переменные для значений оттенка, насыщенности и яркости. Это позволит легко создавать более тёмные или светлые, или менее насыщенные варианты исходного цвета.
:root {
--h: 265;
--s: 70%;
--l: 50%;
--primary: hsl(var(--h) var(--s) var(--l));
--primaryDark: hsl(var(--h) var(--s) 35%);
--primaryLight: hsl(var(--h) var(--s) 75%);
}
HSL может быть невероятно полезным при создании цветовых схем, о чём подробно расписано в статье «Building a Color Scheme» Адама Аргайла (Adam Argyle). В статье он создаёт светлые, тёмные и неяркие цветовые схемы, взяв за основу фирменный цвет. Мне нравится этот подход, потому, что он позволяет детально контролировать вариант цвета (например, уменьшить насыщенность цветов в "тёмной" схеме). Но при этом сохраняет больше преимущество пользовательских свойств: обновление цвета бренда всего в одном месте будет перенесено на всю цветовую схему, что, вероятно, сэкономит нам много времени в будущем.
Цветовые функции Sass
Когда дело доходит до смешивания и настройки цветов, Sass уже много лет предоставляет такие цветовые функции. Мы можем увеличивать или уменьшать насыщенность, делать цвет светлее или темнее, даже смешать два цвета вместе. В некоторых случаях это отлично работает, но есть ограничения: во-первых, мы можем использовать их только на этапе компиляции, а не для управления цветами в браузере. Во вторых, они ограничены RGB и HSL, поэтому страдают от тех же проблем единообразия восприятия, как мы можем увидеть в этой демонстрации, где цвет становится всё более или менее насыщенным, но кажется всё более светлым при преобразовании в оттенок серого.
Что обеспечить равномерность яркости, мы могли бы использовать переменные с LCH, по аналогии с HSL приведённой выше.
li {
--hue: calc(var(--i) * (360 / 10));
background: lch(50% 45 var(--hue, 0));
}
Смешивание цветов и манипуляции
Смешивание цветов
CSS пока не позволяет смешить цвета в браузере. Но это скоро изменится: CSS Color Module Level 5 (рабочий проект) содержит предложения по функциям смешивания цветов, которые звучат многообещающе. Первая функция color-mix()
смешивает два цвета, как mix()
в Sass, но color-mix()
в CSS позволяет указать цветовое пространство и по умолчанию использует LCH, в результате чего достигается превосходное смешивание.
Цвета необязательно должны быть в LCH при передаче в качестве аргумента, но интерполяция будет использовать указанное цветовое пространство. Мы можем указать сколько каждого цвета нужно смешать, аналогично градиенту:
.my-element {
/* равное количество красного и синего */
background-color: color-mix(in lch, red, blue);
}
.my-element {
/* 30% красного, 70% синего */
background-color: color-mix(in lch, red 30%, blue);
}
Цветовая контрастность и доступность
color-contrast()
ещё одна предлагаемая функция, которая действительно имеет огромное значение для выбора доступных цветов. Фактически она разработана с учётом, в первую очередь, доступности. Это позволит браузеру выбрать наиболее подходящее значение из списка, сравнив его с другим цветом. Мы даже можем указать желаемый коэффициент контрастности, что бы наши цветовые схемы соответствовали рекомендациям WCAG (Web Content Accessibility Guidelines). Цвета оцениваются слева направо, и браузер выбирает первый цвет из списка, который соответствует желаемому соотношению. Если, ни один из цветов не соответствует этому соотношению, будет выбран самый контрастный цвет.
.my-element {
color: wheat;
background-color: color-contrast(wheat vs bisque, darkgoldenrod, olive, sienna, darkgreen, maroon to AA);
}
Поскольку сейчас color-contrast()
не поддерживает ни один браузер, я взял этот пример из спецификации. Когда браузер вычислит выражение, результирующий цвет будет darkgreen
, так как он первый из списка, кто соответствует соотношению контрастности AA
для цвета 'wheat'.
Поддержка браузером
CSS Color Module Level 5 в настоящее время находится в Рабочий Проекте, что означает, что ни один из браузеров ещё не поддерживает color-contrast()
и color-mix()
, и их синтаксис может измениться. Но это определённо выглядит, как светлое будущее для цвета в интернете!
Воздействие цветов на окружающую среду
Знаете ли вы, что выбранная вами цветовая палитра может повлиять на то, сколько энергии использует ваш сайт. На OLED-экранах (которые используются в большинстве современных телевизоров и ноутбуков) более тёмные цвета потребляют значительно меньше энергии, чем светлые: белый — больше всего, а чёрный — меньше всего. По словам Тома Гринвуда(Tom Greenwood), автора книга «Устойчивый веб-дизайн», синий также более энергоёмкий, чем цвета в красной и зелёной областях спектра. Что бы уменьшить воздействие ваших приложений на окружающую среду, рассмотрите использование более тёмной цветовой схемы, используйте меньше синего или возможность включения "тёмной темы" для ваших пользователей. В качестве дополнительного бонуса, более экологичный выбор цветов так же может снизить влияние на автономность работы мобильных устройств.