Как преобразовать цвета пространства oklch в rgb в проекте, собираемом с помощью vite

Я прочитал перевод статьи Андрея Ситника «OKLCH в CSS: по­че­му мы ушли от RGB и HSL» и, вдохновившись материалом, решил попробовать поработать с новым цветовым пространством.

Хорошей площадкой стала песочница, в которой продолжаю разбираться с «Реактом». В этом подходе к изучению фреймворка я не стал использовать популярный «Криэйт Реакт Апп» (create-react-app), а воспользовался шаблоном «Реакта», который предлагает «Вит» (vite) — альтернативный, используемому в «Криэйт Реакт Апп», «Вебпаку» инструмент сборки.

О чём речь

OKLCH — новый способ определять цвета в вебе. Он, схож по устройству с хорошо знакомым HSL:

  • L + C + H = яркость (lightness) + насыщенность (chroma) + тон (hue);
  • H + S + L = тон (hue) + насыщенность (saturation) + яркость (lightness).

Но имеет ряд важных преимуществ перед HSL:

  • передаёт яркость так, как её видит человек;
  • яркость не меняется при смене тона;
  • позволяет использовать больше оттенков (актуально для новых устройств, поддерживающих P3-цвета).

В чём проблема

В поддержке браузерами. На 12 июня 2023 года, когда я пишу эти строки, новое цветовое пространство поддерживают 83,74% браузеров. Много, но 16% пользователей, чьи браузеры всё ещё не могут работать с OKLCH — это тоже внушительная цифра. Нельзя пренебрегать этими людьми.

Как решить

При помощи старого-доброго «Пост ЦСС».

Кто не знает, «Пост ЦСС» (Post CSS) — это инструмент для преобразования ЦСС с помощью «Яваскрипта». Сам по себе он ничего не делает, а представляет собой платформу для анализа и трансформации ЦСС основанную на плагинах, которые выполняют те или иные задачи, в зависимости от назначения.

Одним из таких плагинов является «Пост ЦСС пресет энв» (PostCSS Preset Env), который автоматически преобразует разные новые функции и свойства ЦСС в хорошо понятные старым браузерам штуки (каким именно, можно указать в конфиге).

«Вит», из коробки имеет поддержку «Пост ЦСС», поэтому всё что нам нужно — установить «Пресет энв»:

npm install postcss-preset-env postcss

После этого надо добавить плагин в файл package.json (есть и другие способы конфигурировать «Пост ЦСС», я выбрал этот.)

Следующие строчки, дописал в package.json:

"postcss": {
  "plugins": {
    "postcss-preset-env": true
  }
}

Чтобы плагин понимал какие браузеры я хочу использовать, добавил поле browserslist всё в тот же package.json:

"browserslist": [
  "last 10 versions",
  "not dead",
  "not ie <= 11"
]

В данном случае попросил плагин учитывать требования последних десяти версий браузеров, поддержка которых не прекращена. «Интернет Эксплорер» поддерживать не надо.

Результат

После настройки плагина, цвет, наподобие:

background-color: oklch(95% 0.2 35);

Преобразовывается в:

background-color: rgb(255, 230, 222);
background-color: color(display-p3 1 0.89809 0.85552);

Но есть один нюанс

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

Вот так, в итоговом CSS мы получим OKLCH без изменений.

--hue: 82;
--c-ui-a1-default: oklch(87% 0.15 var(--hue));

А вот так всё будет хорошо, конвертация отработает как положено.

--c-ui-a1-default: oklch(87% 0.15 82);
Подборка обложек к постам со старого сайта
Особенности схлопывания границ в ХТМЛ-таблицах