16 января 2025 г.

Тёмная тема: как она устроена и как с ней работать

Время чтения: 6 минут

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

Немного теории

Мы привыкли к использованию цветовой модели RGB, где любой цвет можно представить как сочетание 3-х основных цветов: R — красного, G — зеленого и B — синего. В компьютерной графике интенсивность каждого из основных цветов чаще всего варьируется от 0 до 255. Например, при минимальной интенсивности всех трёх цветов (R=0, G=0, B=0) получается чёрный цвет, а при максимальной (R=255, G=255, B=255) — белый. Этот принцип положен не только в математическую модель, но и воплощен в привычных нам мониторах. Каждый пиксель состоит из трёх субпикселей — красного, зелёного и синего. В зависимости от яркости их свечения мы видим определённый цвет благодаря эффекту пространственного смешивания, а при отсутствии свечения наблюдаем чёрный цвет.

Темная тема: модель

При работе с кодом или графическими редакторами чаще всего применяется шестнадцатеричное (Hex) представление цвета, записанное вместе, например #6812FC. При этом перед кодом всегда следует символ #, который указывает на способ задания значения. В нашем примере получается, что это цвет:

R = #68 = 104
G = #12 = 18
B = #FC = 252

Помимо RGB существуют и другие цветовые модели, например CMYK, применяемая для вывода изображения на печать. Здесь C — отвечает за Cyan (Синий), M — Magenta (Пурпурный), Y — Yellow (Желтый) + K — черный.

Темная тема: модель CMYK

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

Но нас сегодня будет интересовать немного другой подход к представлению цвета. Давайте рассмотрим еще одну цветовую модель — HSL, которая включает три компонента:

  • Hue (Тон)
  • Saturation (Насыщенность)
  • Lightness (Светлота).

Хотя иногда светлоту называют «яркостью», это не совсем корректно, правильнее будет использовать термин «светлота» или «интенсивность».

Тон принимает значение от 0 до 360 градусов; насыщенность — значение от 0 до 1; светлота — также от 0 до 1.

Как же работает тёмная тема

Многие почтовые клиенты имеют функцию автоматического перекрашивания письма в случае, если в приложении (или системе) пользователя включена тёмная тема интерфейса, чтобы светлое письмо не «било по глазам». Выглядит это примерно так:

Емейл с тёмной темой

Светлый фон с тёмным текстом преобразуется в тёмный фон со светлым текстом. При этом чаще всего, если фон изначально был тёмным, то он остаётся неизменным. Причём мы видим не просто какую-то инверсию цвета, а сохранение тона и насыщенности: инвертируется лишь светлота. Ничего не напоминает? =)

Для решения задачи в самом простом случае необходимо представить цвет, используя HSL-цветовую модель, и инвертировать последнюю компоненту — светлоту. Она принимает значение от 0 до 1, то есть нам нужно из единицы вычесть значение светлоты нашего цвета. Поэтому черный становится белым, а белый — черным. чем ближе значение к 0.5, тем меньше изменений мы видим.

Разберём на примере

У нас есть кнопка с цветом фона #6A66D3 и цветом текста #FFFFFF

Пример кнопки

Для начала переведем цвет из 16-ричной системы счисления в десятичную.

#6A66D3 = R 106, G 102, B 211
#FFFFFF = R 255, G 255, B 255

Следующим шагом необходимо перевести цвет из RGB в HSL, для этого воспользуемся следующим алгоритмом:

Dif = Max([R,G,B])-Min([R,G,B]) = 0,4274
Lightness = (Max([R,G,B])+Min([R,G,B]))/2 = 0.6137

Saturation = Dif/(2-Max([R,G,B])-Min([R,G,B])), Если Lightness > 0.5
Saturation = Dif/(Max([R,G,B])+Min([R,G,B])), Если Lightness < 0.5

Saturation = 0.5527

Hue = 0, если Dif = 0
Hue = ((G - B)/Dif mod 6)/6*360, если Max = R
Hue = ((B - R)/Dif + 2)/6*360, если Max = G
Hue = ((R - G)/Dif + 4)/6*360, если Max = B

Hue = 242

Итого, мы получили:

#6A66D3 = H 242, S 0.55, L 0.61
#FFFFFF = H 0, S 0, L 1

Чтобы получить цвет для тёмной темы, пересчитаем значение светлоты, вычтя из единицы значение цвета:

H 242, S 0.55, L (1-0.61) = 0,39
H 0, S 0, L (1-1) = 0

Переводя цвета в RGB, мы получим:

#302C9A
#000000

Или же визуально:

Пример кнопки с темной темой

Примерно так работает преобразование в тёмную тему в почтовом клиенте Gmail на iOS — просто инвертируя светлоту каждого из цветов.

Вместо всех этих вычислений вы можете увидеть значение цвета в RGB и HSL в любом профессиональном графическом редакторе, например, в Figma или Photoshop.

Что перекрашивать

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

Здесь каждый разработчик волен выбирать значения, которые ему по душе, или «поиграться» с ними. Эмпирически мы подобрали значение светлоты 0,6. Если фон светлее (больше) этого значения, его следует перекрасить. Аналогично, если текст темнее 0,6, его также нужно перекрасить.

В реальных почтовых клиентах все происходит чуть-чуть сложнее. Используется прогрессивная шкала корректировки яркости (а не просто вычитание из единицы): чем значение ближе к пороговому (в нашем случае — 0.6), тем меньше цвет будет изменяться. Кроме того, обычно происходит небольшая коррекция насыщенности.

Инструменты

Мы разобрали теорию, где же это может пригодиться на практике и в каких инструментах уже реализовано?

TJML framework и тестирование тёмной темы

При профессиональной верстке писем важно позаботиться не только о качественном отображении в различных почтовых клиентах, но также и об отображении в тёмной теме.

Специально для этого в TJML-фреймворке предусмотрен инструмент тестирования отображения в тёмной теме, а также в тёмной теме, характерной для gmail на iOS:

Тестирование темной темы

Здесь реализован именно тот алгоритм, который мы пошагово рассмотрели выше. Следует отметить, что проверить можно не только письма, созданные на фреймворке — в тело письма (m-body) можно вставить и обычную емейл-верстку.

Pixcraft Плагин для Figma

Этот плагин для Figma также позволяет создавать профессиональные емейл-рассылки, но уже без кода. Он преобразует структуру дизайн-макета в TJML-верстку автоматически, после чего позволяет выгрузить получившийся код в виде архива или в ESP.

Так как TJML-фреймворк является неотъемлемой частью инструмента, то и все преимущества его использования здесь также доступны, в том числе и проверка отображения письма в тёмной теме:

Проверка темной темы

Dark me плагин для Figma

Мы не зря говорили про HSL в контексте работы с цветом — это один из самых удобных подходов, который мы воплотили в плагине Dark me.

Плагин для темной темы

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

Поделиться: