Руководство по современным цветам CSS - RGB, HSL, HWB, LAB и LCH

  alexei 06/01/2022 - 09:52
Руководство по современным цветам CSS - RGB, HSL, HWB, LAB и LCH

Знаете ли вы, что выбранная вами цветовая палитра может влиять на количество потребляемой вашим сайтом энергии? И выбор определенных цветов может увеличить время автономной работы мобильных устройств. В этой статье даются советы по не очень очевидным вещам, о которых следует помнить, работая с цветами в CSS.

В Интернете есть много вещей, которые можно раскрасить. И их гораздо больше, чем кажется на первый взгляд, от чего работать дизайнеру становится все интереснее! Сегодня мы рассмотрим лучшие способы использования цветов в системе дизайна и то, что можно ожидать от этого в ближайшем будущем.

Хорошо известные цветовые значения

Существует множество различных способов определения цветов в CSS. И один из самых простых способов задать цвет для элемента - это использовать строковые имена цветов:


.my-element {
  background-color: red;
}

Они очень ограничены и редко подходят для реальных проектов! Мы также можем использовать шестнадцатеричные значения цвета. Например, следующий код задает для элемента красный цвет фона:


.my-element {
  background-color: #ff0000;
}

Но если вы не специалист по цветам, то шестнадцатеричные значения будет очень трудно прочитать. Маловероятно, что вы сможете слету угадать цвет элемента, посмотрев на шестнадцатеричное значение. При создании макета веб-сайта дизайнер может предоставить нам шестнадцатеричное значение цвета, но если нас попросят сделать его, скажем, на 20% темнее, то нам будет трудно осуществить это, просто изменив шестнадцатеричное значение не обращаясь к визуальным руководствам или средствам выбора цвета.

RGB

Обозначение RGB (красный, зеленый, синий) - это альтернативный способ записи цветового значения, предоставляющий нам доступ к тому же диапазону цветов, что и шестнадцатеричные значения, но в гораздо более понятной форме. Для этого у нас есть CSS функция rgb(). Цвета в cети являются аддитивными, то есть чем выше доля красного, зеленого и синего, тем светлее будет полученный цвет. Если мы используем только красный канал, результат будет красным:


.my-element {
  background-color: rgb(255, 0, 0);
}

Установка максимального значения для красного, зеленого и синего каналов приведет к появлению белого цвета:


.my-element {
  background-color: rgb(255, 255, 255);
}

Используя CSS функцию 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 – яркость). Эту возможность предоставляют CSS функции hsl() и hsla(). Для разработчика этот подход более интуитивно понятнен, когда дело доходит до настройки значений цвета. Например, мы можем получить более темные и светлые варианты одного и того же цвета просто изменив параметр яркости:


.my-element {
  background-color: hsl(0deg, 100%, 20%); // темно-красный
}

.my-element {
  background-color: hsl(0deg, 100%, 50%); // умеренно красный
}

.my-element {
  background-color: hsl(0deg, 100%, 80%); // светло-красный
}

Три цвета демонстрирующие результат работы кода из предыдущего примера
Три цвета демонстрирующие результат работы кода из предыдущего примера

Первый параметр, оттенок, представляет положение на цветовом круге и может иметь любое значение между 0 и 360deg. Функция также принимает единицы поворота - turn (например, 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%);
}

Совет: Если удерживая нажатой клавишу SHIFT кликнуть на цвет в инспекторе панели разработчика в браузерах Chrome и Firefox, то вы переключите значение цвета между шестнадцатеричным, RGB и HSL!

Функции hsl() и hsla() хорошо поддаются манипуляциям с пользовательскими свойствами, что мы вскоре и увидим.

currentColor

Ключевое слово currentColor стоит упомянуть как еще один способ настройки цвета элемента, который уже некоторое время существует. Это эффективно позволяет использовать текущий цвет текста элемента в качестве переменной. Этот способ довольно ограничен по сравнению с пользовательскими свойствами, но часто используется для настройки цвета заливки значков SVG, чтобы задать им такой же цвет, что и цвет текста их родительского элемента.

Современный синтаксис определения цвета

Цветовой модуль CSS уровня 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 – это аббревиатура от оттенок, белизна и чернота (англ. (h)ue, (w)hiteness, (b)lackness). Как и HSL, оттенок может быть в любым на цветовом колесе в диапазоне от 0 до 360. Два других аргумента определяют, сколько белого или черного смешивается с этим оттенком, до 100% (что приведет к полностью белому или полностью черному цвету). Если подмешивать равное количество белого и черного, цвет становится все более серым. Можно думать об этом как о смешивании красок. Особенно полезен этот подход для создания монохромных цветовых палитр.

Пять цветов из HWB значений с разным количеством белого/черного
Пять цветов из HWB значений с разным количеством белого/черного

LAB

LAB и LCH в спецификации определяются как цвета, не зависящие от устройства. LAB - это цветовое пространство, доступ к которому можно получить в программном обеспечении, таком как Photoshop, и рекомендуется, если вы хотите, чтобы цвет на экране выглядел так же, как, скажем, при печати на футболке. Он использует три оси: яркость - (l)ightness, за ось a (от зеленого до красного) и ось b (от синего до желтого).

Яркость выражается в процентах, как в HSL, но при этом может превышать 100% при использовании функции lab(). Очень яркие белые оттенки могут использовать значения до 400%. Значения для осей a и b могут варьироваться от положительных до отрицательных. Два отрицательных значения приведут к цвету в направлении зеленого/синего конца спектра, в то время как два положительных значения могут придать более оранжевый/красный оттенок.


.my-element {
  background-color: lab(80% 100 50); // красновато-розовый
}

.my-element {
  background-color: lab(80% -80 -100); // синий/бирюзовый
}

Пример цветов при положительных и отрицательных значениях a/b в LAB
Пример цветов при положительных и отрицательных значениях a/b в LAB

LCH

LCH означает яркость, цветность и оттенок - (l)ightness, (c)hroma, (h)ue. Как и в случае с LAB, яркость может задаваться в процентах превышающих 100%. Как и в случае с HSL, оттенок может находиться в диапазоне от 0 до 360. Цветность представляет собой количество цвета, и можно воспринимать его как подобие насыщенности в HSL. Однако цветность может превышать значение 100 - теоретически она неограниченна. Пример использования:


.my-element {
  background-color: lch(80% 100 50);
}

.my-element {
  background-color: lch(80% 240 50); // этот цвет за пределами отображения современных браузеров
}

Тем не менее, существует ограничение на количество цветов, которые сегодня могут отображать браузеры и мониторы, поэтому значения выше 230 вряд ли будут работать, так как цветность уменьшается до тех пор, пока она не окажется в пределах диапазона отображения.

Четыре LCH цвета с оттенком красного при изменении уровня цветности
Крайний справа цвет находится за пределами отображаемого диапазона, поэтому отличия не видны

Зачем же нужны LAB и LCH, когда есть HSL? Одна из причин заключается в том, что использование LAB или LCH дает доступ к гораздо большему диапазону цветов. LCH и LAB предназначены для того, чтобы предоставить нам доступ ко всему спектру человеческого зрения. Кроме того, HSL и RGB имеют несколько недостатков: они неоднородны по восприятию, и в HSL увеличение или уменьшение яркости имеет разный эффект в зависимости от оттенка.

На следующей картинке можно увидеть резкий контраст между LCH и HSL при переключении на оттенки серого. Для полос оттенка (hue) и насыщенности (saturation) HSL есть явные различия в воспринимаемой яркости каждого квадрата, даже несмотря на то, что компонент "яркость" функции HSL один и тот же! В то же время полосы цветности (chroma) и оттенка (hue) в случае с LCH имеют почти одинаковую яркость восприятия.

Сравнение цветов LCH и HSL
При преобразовании в оттенки серого видно, что у цветов LCH (слева) почти одинаковая яркость при изменении цветности (chroma) и оттенка (hue), в то время как при изменении оттенка (hue) и насыщенности (saturation) у цветов HSL (справа) яркость отличается.

Также значительная разница заметна при использовании цвета LCH для создания градиентов. Оба градиента на следующем изображении начинаются и заканчиваются одним и тем же цветом. Однако градиент LCH в середине имеет яркие оттенки синего и фиолетового цвета, в то время как градиент HSL по сравнению с ним выглядит более мутным и размытым.

Полоса градиента от синего к розовому в LCH и HSL
Полоса градиента от синего к розовому в LCH и HSL

Хотя LAB и LCH, возможно, синтаксически немного менее интуитивно понятны, выдают цвета, которые имеют больше смысла для человеческого глаза.

Как и в случае с другими цветовыми функциями, hwb(), lab() и 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. Таким образом, использование значений за пределами диапазона sRGB будет иметь эффект только тогда, когда оборудование и браузеры продвинутся достаточно далеко.

В настоящее время Safari поддерживает функцию color(), которая позволяет отображать цвета в пространстве P3, но на данный момент они ограничены цветами RGB и пока не дают всех преимуществ LAB и LCH.


.my-element {
  background: rgb(98.38% 0% 53.33%); // ярко розовый
  background: color(display-p3 0.947 0 0.5295); // аналог в цветовом пространстве P3
}

Управление цветами

Более широкий набор цветовых функций означает, что у нас появляется больше возможностей для управления цветами в приложении. Часто нам требуется несколько вариантов одного конкретного цвета в системе дизайна, от темного до светлого.

Пользовательские свойства

Пользовательские свойства CSS позволяют нам хранить значения для повторного использования в наших таблицах стилей. Поскольку они допускают частичные значения свойств, они могут быть особенно полезны для управления и манипулирования значениями цвета. HSL особенно хорошо подходит для пользовательских свойств благодаря своей интуитивности. Так, например, можно использовать пользовательские свойства для настройки оттенка для каждого сегмента цветовой полосы, вычисляя значение --hue на основе индекса элемента (определенного в другом пользовательском свойстве).


li {
  --hue: calc(var(--i) * (360 / 10));
  background: hsl(var(--hue, 0) 50% 45%);
}

Также можно, например, вычислять значения дополнительных цветов (значений с противоположных сторон цветового круга).

Перевод HEX/RGB в HSL

До определенного момента цвета RGB могут удовлетворять вашим потребностям, но если вам нужна гибкость, чтобы, например, иметь возможность получать новые оттенки из вашей базовой цветовой палитры, то вам, возможно, стоит перейти на HSL (или LCH, если они поддерживаются). Для этого отлично подходят пользовательские свойства.

Примечание: Существует множество онлайн-ресурсов для преобразования шестнадцатеричных или RGB-значений в HSL

Возможно, у вас есть цвета, сохраненные как переменных 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%);
}

Цветовые функции SASS

В Sass уже давно есть цветовые функции, которые позволяют делать с цветом практически все что угодно. Мы можем увеличивать или уменьшать насыщенность цвета, осветлять или затемнять его и даже смешивать два цвета. В некоторых случаях это отлично работает, но есть некоторые ограничения. Во-первых, мы можем использовать эти функции только во время компиляции таблиц стилей, но никак не для управления цветами в браузере. Во-вторых, эти функции работают только RGB и HSL цветами, поэтому они страдают от тех же проблем единообразия восприятия. Как можно видеть на следующем изображении, цвет становится все более ненасыщенным, но при преобразовании в оттенки серого становится более светлым.

При уменьшении насыщенности красного цвета с помощью Sass, цвет становится светлее
В верхней половине изображения применен фильтр оттенков серого. Когда мы уменьшаем насыщенность красного цвета с помощью Sass (внизу), мы видим, что цвет на самом деле становится светлее.

Чтобы гарантировать, что яркость останется равномерной, мы могли бы использовать пользовательские свойства с LCH аналогично описанному выше способу с HSL.


li {
  --hue: calc(var(--i) * (360 / 10));
  background: lch(50% 45 var(--hue, 0));
}

Смешивание и манипулирование цветами

Смешивание цветов

Одна вещь, которую CSS пока не позволяет нам делать - это смешивать цвета прямо в браузере. Однако все скоро изменится - спецификация цвета CSS уровня 5 (рабочий проект) содержит предложения по функциям смешивания цветов, которые звучат довольно многообещающе. Первая - это функция color-mix(), которая смешивает два цвета и очень похожа на Sass функцию mix(). Но 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. Цвета обрабатываются слева направо, и браузер выбирает первый цвет из списка, соответствующий желаемому соотношению. Если ни одно из значений не соответствует заданному соотношению, то выбранный цвет будет наиболее контрастным.


.my-element {
  color: wheat;
  background-color: color-contrast(wheat vs bisque, darkgoldenrod, olive, sienna, darkgreen, maroon to AA);
}

Поскольку в данный момент эта функция не поддерживается ни в одном браузере, то приведенный пример взят непосредственно из спецификации. Когда браузер просчитает выражение, то получившийся цвет будет darkgreen, так как он является первым, который соответствует коэффициенту контрастности AA по сравнению с цветом текста wheat.

Поддержка браузерами

Спецификация цветов уровня 5 в настоящее время находится в состоянии рабочего проекта. Это означает, что браузеры еще не поддерживают функции color-mix() и color-contrast(), и их синтаксис еще может быть изменен. Но это, безусловно, выглядит как светлое будущее для управления цветами в Интернете!

С недавнего времени в Safari 15 появилась возможность в экспериментальном режиме использовать функции color-mix() и color-contrast().

Воздействие цветов на окружающую среду

Знаете ли вы, что выбранная вами цветовая палитра может повлиять на количество потребляемой энергии вашим сайтом? На OLED экранах (которые сейчас у большинства современных телевизоров и ноутбуков) темные цвета потребляют значительно меньше энергии, чем светлые, причем белый потребляет больше всего энергии, а черный - меньше всего. По словам Тома Гринвуда, автора книги "Устойчивый веб-дизайн" (Tom Greenwood "Sustainable Web Design"), синий также более энергоемкий, чем цвета в красной и зеленой областях спектра. Чтобы уменьшить воздействие ваших приложений на окружающую среду, рассмотрите возможность использования более темной цветовой схемы, в которой было бы как можно меньше синего цвета, либо предоставьте вашим пользователям возможность включения темного режима. В качестве дополнительного бонуса более экологичный набор цветов также может увеличить время автономной работы мобильных устройств.