Проблема традиционных цветовых пространств
Традиционно в IT используются RGB или HSL.
Основная проблема этих цветовых моделей заключается в том, что они нелинейны с точки зрения человеческого восприятия.
RGB
Для примера возьмем равномерные ступенчатые градиенты RGB цветов.
- градиент красного — это цвета
#000
,#100
,#200
,#FEE
,#FFF
и т.д.; - градиент зеленого — это цвета
#000
,#010
,#020
и т.д.; - градиент синего — это цвета
#000
,#001
,#002
и т.д.; - градиент желтого — это цвета
#000
,#110
,#220
и т.д.; - градиент голубого — это цвета
#000
,#011
,#022
и т.д.; - градиент пурпурного — это цвета
#000
,#101
,#202
и т.д.
![](https://habrastorage.org/getpro/habr/post_images/91c/815/cb6/91c815cb6c1a7db041abafe49babd28a.png)
Мы можем увидеть несколько вещей:
- Яркость цветов увеличивается неравномерно: чем оттенок ближе к белому цвету, тем изменение яркости меньше;
- Яркость разных цветов различается: синий намного темнее остальных;
- Насыщенность также неравномерна: синий и красный выглядят «ненасыщенными» в правой части градиента.
Хорошо, RGB — это способ визуализации пикселей, да и разрабатывалась эта модель не для удобного «управления» значениями.
HSL
Давайте провернем такую же манипуляцию с HSL. В теории, с HSL проще работать из-за возможности оставить тон постоянным и изменять две оставшиеся переменные — насыщенность и светлоту.
Для каждого ряда постоянными являются насыщенность и тон, а светлота каждого элемента отличается от предыдущего на 3.3%. Формально каждый ряд представляет собой массив из результатов функции
hsl(тон, насыщенность, светлота)
, где насыщенность = 100%, а тон:- красный — 0;
- зеленый — 120;
- синий — 240;
- желтый — 60;
- голубой — 180;
- пурпурный — 300;
![](https://habrastorage.org/getpro/habr/post_images/c4c/86c/75f/c4c86c75fb793a2e2836e0cebe381df9.png)
Цвета такие же, как и в случае с RGB, потому что HSL — это просто способ записи RGB, другое представление той же цветовой модели.
В оставшейся части статьи я буду использовать RGB или HSL как синонимы для обозначения цветовой модели RGB.
HSLuv
В 1970-х годах Международная комиссия по освещению разработала цветовую модель CIELAB. В то же время была представлена другая цветовая модель CIELUV. Обе модели не зависят от устройства и стремятся к единообразию восприятия. Это подразумевает попытку приблизиться к человеческому зрению, что будет продемонстрировано на примерах ниже.
CIELUV использует светлоту (L) и хроматические координаты (uv), с которыми не очень удобно работать. По этой причине Алексей Боронин (Alexei Boronine) пришел к HSluv. Это цветовое пространство позволяет использовать CIELUV с более простым трио HSL: тон(Hue), насыщенность(Saturation) и светлота (Lightness).
Давайте представим те же градиенты, аналогичные предыдущим:
![](https://habrastorage.org/getpro/habr/post_images/c10/ecd/10e/c10ecd10e62995e0c801ae85ec1394b5.png)
Полученные оттенки выглядят несколько «причудливо», но зато шаги между элементами стали более «постоянными», что, как мы увидим дальше, очень важно.
Сравнение HSLuv и RGB
Примеры для этого раздела взят из блога Алексея Боронина.
Цвета одинаковой светлоты
![](https://habrastorage.org/getpro/habr/post_images/85f/434/593/85f4345937fb230355c1a4e51266b51e.png)
Правые и левые цвета должны быть одинаковой светлоты. В случае с HSL, заметно, что желтый цвет намного ярче, чем синий. HSLuv выдаёт относительно одинаковый результат.
Проблема светлоты с HSL проявляется лучше всего, когда мы используем цвета в качестве фона для белого текста. С теми же цветами, что и выше получаем следующий результат:
![](https://habrastorage.org/getpro/habr/post_images/086/6ef/ea4/0866efea4bda60bfb8589dfdbee91120.png)
Цвета одинаковой насыщенности
![](https://habrastorage.org/getpro/habr/post_images/2b2/92a/cf5/2b292acf5b1919ab8ba6302343cd5bd5.png)
Правые и левые цвета должны быть одинаковой насыщенности. Красный цвет в HSL выглядит более насыщенным, а в случае с HSLuv насыщенность цветов относительно одинакова.
Разница между цветами
Давайте сравним четыре цвета. Два верхних имеют такую же разницу в тонах, как и два нижних:
![](https://habrastorage.org/getpro/habr/post_images/c4d/edb/201/c4dedb2018b10e276bc068fd48484ac2.png)
Два верхних цвета существенно различаются, в то время как нижние — практически сливаются.
![](https://habrastorage.org/getpro/habr/post_images/04e/16c/c53/04e16cc53081478e73aaba3c42214723.png)
В HSLuv разница в тонах между цветами примерно равная.
Практические примеры
Теперь, после ознакомления с HSLuv, давайте рассмотрим практические примеры.
Пользовательские цвета
Одним из самых распространенных примеров является создание пользовательских цветов для интерфейса. Цвета папок, кнопок, тегов, меток и… В общем, всё, что пользователь может настроить по своему усмотрению.
Если предоставить пользователю возможность выбирать цвета из полной палитры, то вы получите неуправляемые цвета. Поэтому вам необходимо ограничить выбор пользователя. Первый вариант — это выбрать перечень цветов заранее и предоставить пользователю ограниченную палитру. Второй вариант — это позволить пользователю выбрать сначала тон, а затем насыщенность и светлоту.
Пример «Labels»
В следующих примерах цвет выбирается следующим образом:
- тон одинаков для фона и текста;
- насыщенность всех цветов — 80;
- 4 первых пары имеют светлоту фона — 30 и текста — 80;
- 4 последних имеют яркость фона — 70 и текста — 20.
![](https://habrastorage.org/getpro/habr/post_images/46a/c73/f05/46ac73f05dc08f2b827324c3380d52c4.png)
Как мы видим, цвета HSLuv образуют более статичную (в плане визуальной разницы светлоты) пару и не создают риск сломать пользовательский интерфейс или сделать метку неразборчивой.
Создание палитры
Ещё одно распространенное использование HSLuv — это программная генерация палитры цветов. При работе над приложением у вас может быть фирменный цвет заказчика и всё.
Допустим, ваш клиент или работодатель предоставил вам свой фирменный цвет
#00916c
. Это всё, что вам необходимо для разработки цветовой палитры приложения.С HSLuv очень легко создать палитру.
Сначала мы конвертирует цвет
#00916c
в HSLuv, получая 155.7, 100, 53.4
. Округляя, получаем тон 156.Исходя из полученного значения, мы можем выбрать дополнительный тон. Есть несколько способов сделать это, но мы просто возьмем противоположный тон (±180°) и получим дополнительный тон
336
:![](https://habrastorage.org/getpro/habr/post_images/943/80f/ce4/94380fce4775766a962ae76bd3fc1145.png)
Палитра для темной темы (выше) и светлой (ниже). Пара чисел над каждым цветом — это насыщенность, светлота.
Слева направо:
- тон фона — 156;
- тон текста — 156;
- тон выделения — 156;
- тон фона кнопки — 156;
- тон текста кнопки — 156;
- тон фона кнопки по умолчанию — 336;
- тон текста кнопки по умолчанию — 336.
Для темной темы акцент был ненасыщенным, а для светлой наоборот.
Не существует абсолютного и объективного правила создания цветов, но светлотой и насыщенностью можно управлять интуитивно, чтобы создавать сочетающиеся наборы цветов. При создании цветов в этой статье я делал именно так — следовал своей интуиции.
Палитра в использовании
![](https://habrastorage.org/getpro/habr/post_images/cab/8a4/716/cab8a4716ecd34b33ef59646e78ab10a.png)
Палитру можно создать за несколько секунд, выбрав цвета вручную.
Теперь взглянем на ту же палитра с HSL/RGB:
![](https://habrastorage.org/getpro/habr/post_images/d5a/269/dd3/d5a269dd347f9b5dda2e73fd44f1f01f.png)
Цветовую палитру HSLuv можно использовать непосредственно в дизайне, при этом палитра HSL требует настройки перед применением. Также палитра HSL не может создавать стабильно одинаковые по насыщенности, тону и светлоте вариации.
Варианты палитры
Используя те же наборы насыщенности и светлоты можно создать новую палитру с другим тоном.
- тон = 200:
![](https://habrastorage.org/getpro/habr/post_images/be9/bd4/101/be9bd4101a18b53fc2a8c87f145452cf.png)
- тон = 300:
![](https://habrastorage.org/getpro/habr/post_images/1bf/ef1/00f/1bfef100fae4de401bf6efc7e444e88b.png)
- тон = 50:
![](https://habrastorage.org/getpro/habr/post_images/811/d03/e00/811d03e00eb6267100ff1a79b1741c58.png)
- тон = 260 со светлой темой и акцентным цветом +60:
![](https://habrastorage.org/getpro/habr/post_images/83c/1f6/5a3/83c1f65a3475da397ac4067a0ccf4141.png)
- тон = 160 со светлой темой и акцентным цветом +120(триада):
![](https://habrastorage.org/getpro/habr/post_images/016/9a2/45d/0169a245d5daf53b46da4cc358252386.png)
Как использовать HSLuv
Цвета HSLuv необходимо использовать непосредственно в исходном коде, а не полагаться на внешний редактор. HSLuv переходит в css, js, java. С полным списком доступных языков можно ознакомиться здесь.
Поддержка редакторов и инструментов
В то время как HSLuv доступен для многих языков, ситуация с различными редакторами не столь хороша. Остается надеяться, что скоро мы сможем увидеть палитру цветов HSLuv в редакторах.
Вывод
HSLuv — это отличный инструмент для разработчиков. Он позволяет с легкостью создавать цвета для дизайна, не обращаясь к графическому редактору или дизайнеру. Цвета можно генерировать с помощью простых вычислений, как и палитры. А из-за постоянного контраста, HSLuv идеально подходит для создания тем и динамической цветопередачи.
![](https://habrastorage.org/webt/bh/0m/fv/bh0mfviu_rma7be5uylpewumuxi.png)
Комментарии (5)
Iskin
18.01.2022 01:21Я вместо HSLuv предпочитаю LCH (через LAB).
LCH скоро будет поддерживаться нативно в браузере, что удобно.
Плюс LCH позволяет указать P3-цвета.
Но взамен в LCH при генерации цвета с помощью скрипта надо проверять, что он не вышел за пределы экрана/глаза, в отличии от HSLuv
Spaceoddity
18.01.2022 10:07+2Что-то я из статьи не очень понял разницу между HSL и HSLuv (теоретическую).
Формально каждый ряд представляет собой массив из результатов функции
hsl(тон, насыщенность, светлота)
Это цветовое пространство позволяет использовать CIELUV с более простым трио HSL: тон(Hue), насыщенность(Saturation) и светлота (Lightness).
И? Чем они отличаются?
И ещё момент. Вы в переводе аббревиатуры случайно нигде не спутали Lightness и Luminosity?
vadimk91
18.01.2022 17:16Неужели разработчикам разрешили использовать свою цветовую гамму в приложениях, а не как учил великий гугл (и MS туда же) чуть ли не всё последнее десятилетие: "всё серое на бледно-сером фоне"
{комментарий не разработчика, но пользователя}
foal
По поводу разборчивости текста на фоне существуют рекомендации https://www.w3.org/TR/WCAG/#visual-audio-contrast, которые сводятся к одному числу contrast ratio. С ним можно поиграться здесь https://contrast-ratio.com
Я пробовал рассчитать более контрастные сочетания для ConEmu через HLS: https://github.com/Maximus5/ConEmu/issues/658#issuecomment-215960058 (1.3 -> 1.9). Возможно с HSLuv это будет эффективней.