01

Считайте HWB моделью редактирования sRGB

HWB означает hue, whiteness и blackness. CSS Color 4 определяет его как ещё один способ задать цвет sRGB: берётся полностью насыщенный sRGB-hue, к нему добавляется доля белого, а ещё одна доля резервируется под чёрный. Результат остаётся внутри sRGB, поэтому HWB не открывает Display P3 и другие широкие gamut. Польза модели практическая: color picker сохраняет hue, пока человек регулирует вклад белого и чёрного краёв диапазона.

  • Hue использует тот же круг, что HSL, включая визуально неравномерные расстояния между числовыми углами.
  • Whiteness поднимает минимальный канал sRGB и ведёт результат к белому, не меняя непрозрачность.
  • Blackness снижает максимальный доступный канал и ведёт результат к чёрному, не меняя непрозрачность.
  • HWB приводится к sRGB, поэтому любой непрозрачный результат можно представить эквивалентным HEX или rgb().
  • Координаты HWB — регуляторы, а не доказательство доступности; контраст считается по итоговым отображаемым цветам.
02

Используйте синтаксис с пробелами и отдельным alpha

Функция записывается как hwb(H W B / A). Hue принимает угол или число без единицы, которое интерпретируется в градусах; значения за пределами одного оборота зацикливаются. Whiteness и blackness понятнее всего задавать процентами. Alpha размещается после косой черты и без явного значения равен 100%. В отличие от hsl(), у HWB нет старой формы с запятыми: запятые внутри hwb() делают значение невалидным. Современный CSS также разрешает none для отсутствующего компонента, но none не означает ноль и важен прежде всего при интерполяции.

css
:root {
  --action: hwb(210 10% 20%);
  --action-translucent: hwb(210 10% 20% / 60%);
  --action-wrapped-hue: hwb(570deg 10% 20%); /* Тот же hue, что 210deg */
}

/* Невалидно: у HWB нет синтаксиса с запятыми. */
.invalid-example {
  color: hwb(210, 10%, 20%);
}
Запись HWBИтоговый HEXИтоговый RGBЧто показывает пример
hwb(0 0% 0%)#FF0000255 0 0Чистый красный hue
hwb(120 0% 0%)#00FF000 255 0Чистый зелёный hue
hwb(240 0% 0%)#0000FF0 0 255Чистый синий hue
hwb(210 10% 20%)#1A73CC26 115 204Белый и чёрный добавлены к базовому hue
hwb(570 10% 20%)#1A73CC26 115 204Hue зацикливается через 360 градусов
03

Увеличивайте whiteness и следите за порогом foreground

Зафиксируем hue на 210 градусах и blackness на 20%, после чего увеличим whiteness. Максимальный итоговый канал остаётся на 80%, а меньшие каналы растут. Таблица использует алгоритм HWB-to-sRGB из CSS Color 4, округляет каждый канал до ближайшего 8-битного значения и считает контраст полученного HEX по формуле относительной яркости WCAG. Уровень AA для обычного текста требует не менее 4,5:1.

HWB8-битный sRGBЧёрный текстБелый текстВыбор AA для обычного текста
hwb(210 0% 20%)#0066CC3,77:15,57:1Белый
hwb(210 10% 20%)#1A73CC4,37:14,81:1Белый
hwb(210 20% 20%)#3380CC5,10:14,12:1Чёрный
hwb(210 30% 20%)#4D8CCC5,94:13,54:1Чёрный
hwb(210 40% 20%)#6699CC6,99:13,00:1Чёрный
hwb(210 60% 20%)#99B3CC9,67:12,17:1Чёрный
  • В этой конкретной шкале foreground меняется между whiteness 10% и 20%.
  • При whiteness 10% чёрный даёт только 4,37:1, а белый — 4,81:1; округлённый входной процент не делает оба варианта безопасными.
  • На шаге 40% чёрный получает 6,99:1: это уровень AA, но значение чуть ниже порога AAA 7:1 для обычного текста.
  • Проверяйте каждое семантическое состояние отдельно: один foreground нельзя автоматически переносить на всю HWB-шкалу.
  • Сохраняйте неокруглённые коэффициенты для решения pass/fail, а округляйте только показанное число.
04

Увеличивайте blackness, не смешивая его с opacity

Теперь оставим hue 210 градусов и whiteness 10%. Рост blackness уменьшает доступный вклад чистого hue, а минимальный канал остаётся около 10%. Все строки по-прежнему полностью непрозрачны. Это принципиально отличается от снижения alpha: полупрозрачный цвет показывает неизвестный фон, а HWB с повышенной blackness уже разрешается в полный триплет sRGB. По мере затемнения foreground меняется в обратном направлении.

HWB8-битный sRGBЧёрный текстБелый текстВыбор AA для обычного текста
hwb(210 10% 0%)#1A8CFF6,24:13,37:1Чёрный
hwb(210 10% 10%)#1A80E65,27:13,98:1Чёрный
hwb(210 10% 20%)#1A73CC4,37:14,81:1Белый
hwb(210 10% 30%)#1A66B33,60:15,84:1Белый
hwb(210 10% 40%)#1A59992,93:17,16:1Белый
hwb(210 10% 50%)#1A4D802,42:18,69:1Белый
hwb(210 10% 60%)#1A40661,97:110,66:1Белый
05

Нормализуйте whiteness и blackness при сумме 100%

Главный edge case HWB возникает при W + B не меньше 100%. CSS не отклоняет цвет, а делит обе доли на их сумму и возвращает ахроматический результат, у которого все три канала sRGB равны W / (W + B). Исходный hue не способен изменить этот серый и становится powerless. Поэтому значения с разными суммами, но одинаковым отношением W:B после пересечения границы могут дать один цвет.

Запись HWBW + BНормализованные W:BИтоговый HEXРезультат hue
hwb(45 40% 80%)120%33,33% : 66,67%#555555Не влияет
hwb(200 50% 50%)100%50% : 50%#808080Не влияет
hwb(10 100% 100%)200%50% : 50%#808080Не влияет
hwb(0 70% 70%)140%50% : 50%#808080Не влияет
hwb(320 80% 20%)100%80% : 20%#CCCCCCНе влияет
  • Первая строка — пример нормализации из CSS Color 4: 40 / (40 + 80) даёт серый с уровнем одной трети.
  • Равные whiteness и blackness после достижения границы всегда нормализуются в 50-процентный серый.
  • Не кодируйте семантический hue в ахроматическом токене: изменение угла не меняет отображаемый результат.
  • Если сгенерированная шкала должна сохранять hue, проверяйте W + B < 100% до публикации.
  • Избегайте повторных преобразований через округлённые проценты HWB: рядом с границей отношение W:B может дрейфовать.
06

Преобразуйте RGB, HWB и HSL без потери источника

Для цвета sRGB whiteness в HWB равна наименьшему нормализованному RGB-каналу, а blackness — единице минус наибольший канал. Hue выводится из разницы каналов по той же геометрии, что в HSL. Преобразование детерминировано, но удобное для показа округление необратимо. Храните одно каноническое представление с достаточной точностью, а остальные формы создавайте для документации и copy-кнопок, не перезаписывая ими источник.

HEXRGBПроизводный HWBПроизводный HSLПримечание
#663399102 51 153hwb(270 20% 40%)hsl(270 50% 40%)Точные целые проценты
#FFA500255 165 0hwb(38,82 0% 0%)hsl(38,82 100% 50%)Чистый HWB-hue с дробным углом
#00FFFF0 255 255hwb(180 0% 0%)hsl(180 100% 50%)Чистый циановый hue
#808080128 128 128hwb(none 50,20% 49,80%)hsl(none 0% 50,20%)Hue не влияет
#4F46E579 70 229hwb(243,40 27,45% 10,20%)hsl(243,40 75,35% 58,63%)Сохраняйте дроби для воспроизводимого аудита
07

Публикуйте HWB-токены с проверяемым результатом

Практичный набор HWB-токенов хранит редактируемые координаты, разрешённый sRGB-fallback и проверенные foreground рядом. В прямых CSS-свойствах можно поставить HEX первым, а HWB вторым: ПО, не понимающее позднее значение, сохранит предыдущую декларацию. Такой fallback не решает контраст alpha и не делает непроверенную шкалу доступной — каждому итоговому состоянию всё равно нужны собственные данные.

css
:root {
  --action: hwb(210 10% 20%);
  --action-muted: hwb(210 30% 20%);
  --action-dark: hwb(210 10% 40%);
  --on-action: #FFFFFF;
  --on-action-muted: #000000;
}

.action {
  color: #FFFFFF;
  background: #1A73CC;
  background: var(--action); /* 4,81:1 с белым */
}

.action-muted {
  color: var(--on-action-muted);
  background: #4D8CCC;
  background: var(--action-muted); /* 5,94:1 с чёрным */
}
  • Держите W + B ниже 100%, если выбранный hue должен оставаться видимым.
  • Храните канонические координаты HWB с достаточной точностью, а округлённый HEX экспортируйте как производное значение sRGB.
  • Отдельно тестируйте normal, hover, active, selected, focus, disabled, светлую и тёмную темы.
  • Перед расчётом яркости и контраста скомпозируйте alpha с реальным фоном.
  • Не называйте HWB широкогамутным или перцептивно равномерным: он наследует gamut и ограничения hue от sRGB.
  • Используйте HSL, когда нужны saturation и модельная lightness, а OKLCH — когда требуется перцептивная шкала.
  • Ссылайтесь на спецификацию преобразования и храните неокруглённые значения аудита для воспроизводимости генератора.
S

Первоисточники

Фактические утверждения статьи проверены по этим опубликованным спецификациям.

  1. W3C CSS Color 4 — запись HWB
  2. W3C CSS Color 4 — преобразование HWB в sRGB
  3. W3C CSS Color 4 — преобразование sRGB в HWB
  4. W3C CSS Color 4 — не влияющие на результат компоненты цвета
  5. W3C WCAG 2.2 — относительная яркость
  6. W3C WCAG 2.2 — контраст (минимальный)