Держаться в пределах P3 Сбросить в P3
L C H
H S L
R G B
+0.2 HS(L)
OK(L)CH
+0.02 HS(L)
OK(L)CH
P3
sRGB
-0.02 HS(L)
OK(L)CH
-0.2 HS(L)
OK(L)CH
+0.2 HS(L)
OK(L)CH
+0.02 HS(L)
OK(L)CH
P3
sRGB
-0.02 HS(L)
OK(L)CH
-0.2 HS(L)
OK(L)CH

RGB

RGB — техническая цветовая модель. Она не имеет отношения к человеческому пониманию цвета и описывает то, как дисплеи работают с цветом. Каждый параметр — это яркость элемента пикселя.

HSL

HSL — попытка очеловечить RGB. В этой модели цвет представляется более понятными параметрами: тон, насыщенность и светлота.

Проблема HSL в том, что это всё ещё слишком техническая модель. Конвертация HSL <=> RGB происходит по линейным формулам. Если подвигать ползунки преобразования HSL, можно заметить, что значения RGB меняются линейно и максимально предсказуемо — HSL всё ещё работает с тем, как отображаются цвета на дисплее, а не с тем, как видит их человек.

Чтобы наглядно увидеть суть проблемы, можно взять предложенный по умолчанию цвет (RGB: 0, 0.5, 1) и начать менять значение H в HSL. При H = 240 получается тёмно-синий цвет, на котором чёрные буквы почти не видны. При H=60 уже белые буквы становится плохо видно.

Причин такой разницы как минимум две. Во-первых, человеческий глаз имеет разную чувствительность к разным цветам. Во-вторых, отличается и суммарное значение света, выделяемого одним пикселем. При H равных 0, 120, 240 «светится» только один канал, а при H равном 60, 180, 300 — в два раза больше.

Таким образом, используя HSL, невозможно предсказуемо модифицировать цветовую схему. Нельзя математически проверить допустимость цвета в конкретном месте (в качестве фона под белым текстом, например). Нельзя перекрасить цветовую схему из синей в зелёную путём изменения Hue. В таком случае вместо приятного глазу тёмного синего цвета может вылезти кислотный и слишком светлый зелёный.

Затруднительным с HSL может оказаться и подбор универсальных модификаторов для генерации дополнительных цветов на основе базовых.

Проблемы можно заметить и при изменении насыщенности. Если взять (RGB: 1, 1, 0) и начать уменьшать в нём S (из HSL), то светло жёлтый станет довольно тёмным серым.

OKLCH

Для решения проблем HSL можно использовать OKLCH. Это относительно новая цветовая модель, оперирующая похожими на HSL параметрами: яркость, насыщенность и оттенок. Сначала появилась модель LCH, а OKLCH — это она же, но с доработками.

Необязательно использовать OKLCH как основную рабочую модель — можно брать её в качестве промежуточной. Например, храним и показываем цвета в RGB, но перед трансформациями конвертируем в OKLCH, меняем цвет как хотим, конвертируем обратно, в браузере рисуем RGB.

OKLCH похож на очеловеченный OKLAB. Основное отличие OKLCH от HSL заключается в том, что параметры цвета ориентированы не на принципы работы дисплеев, а на восприятие цветов человеком.

Изменяя цвет фона или текста в OKLCH, можно иметь гораздо больше уверенности в том, что пока мы не трогаем параметр L, контрастность никуда не денется. Можно перекрасить синюю кнопку в зелёный и не бояться, что текст на ней перестанет читаться или от одного взгляда на неё начнут вытекать глаза.

OKLCH даёт и более предсказуемые относительные манипуляции с цветом. Например, изменением L на пару процентных пунктов для фона кнопки можно получить фон для кнопки при наведении. И это изменение имеет более стабильные результаты, чем аналогичная манипуляция с цветом в HSL. Особенно сильно это проявляется на более значительных изменениях яркости.

У OKLCH в качестве промежуточной модели есть один минус, о котором всегда следует помнить. OKLCH кодирует огромное цветовое пространство. Значительную часть цветов, которые позволяет описать OKLCH, невозможно отобразить на экране и записать в других цветовых моделях. Поэтому конвертация происходит с потерями.

Например, если взять насыщенный и умеренно яркий цвет в RGB, перевести его в OKLCH, значительно увеличить L, вернуть L обратно и сконвертировать обратно в RGB, на выходе будет исходный цвет.

Но если взять тот же исходный цвет, сконвертировать в OKLCH, увеличить яркость, сконвертировать в RGB, снова сконвертировать в OKLCH, вернуть яркость и сконвертировать обратно, то может потеряться насыщенность.

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

И в целом из-за работы со слишком широким цветовым диапазоном OKLCH имеет тенденцию давать довольно серые цвета при уменьшении яркости у слишком светлых цветов. Увидеть это можно на «-0.2 OK(L)CH», если выкрутить L у дефолтного синего до 0.9. Иногда в таких ситуациях может показаться, что HSL работает лучше.

Но в общем случае HSL с этим справляется ещё хуже и способен выдавать цвета с совершенно непредсказуемыми характеристиками. Для демонстрации можно взять цвет (HSL: 0, 1, 0.8), подвигать параметр H и понаблюдать, как меняется «-0.2 HS(L)». При этом «-0.2 OK(L)CH» себя показывает достаточно стабильно даже несмотря на значительные изменения цвета, от которого происходит расчёт (если крутить H от HSL).

P3

В качестве внезапного бонуса OKLCH даёт доступ к расширенному цветовому пространству. Пока это работает не на всех дисплеях, но попробовать можно.

Выкручиваем стандартный максимально красный цвет (RGB: 1, 0, 0). После чего в OKLCH задвигаем C (Chroma) до максимума. Если монитор поддерживает P3, то можно заметить, что максимально красный в P3 заметно краснее и ярче, чем максимально красный в sRGB.

Применять такое на практике может быть ещё рано (сложно поддерживать обратную совместимость). Но однажды оно может прийти в каждый дом. Хотя в мобильной разработке уже вполне может использоваться.

В форме управления цветом есть чекбокс «Держаться в пределах P3». Он позволяет «прощупать» границы P3, но при подборе цвета его лучше не использовать — при каждом пересчёте цвета происходит потеря информация о предыдущем, и итоговый цвет может сильно «убегать» от исходного по всем параметрам. Для разового приведения цвета в пространство P3 лучше использовать кнопку «Сбросить в P3».

Визуализацию OKLCH и P3 можно получше рассмотреть на oklch.com.