Глаз воспринимает один и тот же цвет по-разному на светлом и тёмном фоне — это не метафора, а физиология зрения. Насыщенный цвет, который на белом фоне читается как спокойный и статусный, на чёрном начинает вибрировать и вызывать зрительное утомление за счёт эффекта одновременного контраста. Поэтому механическая инверсия (белый→чёрный, тёмно-синий→светло-синий через простой сдвиг HSL) ломает саму идею бренда: цвет должен вызывать одинаковую эмоцию в обеих темах, а не одинаковый код.
Правильная логика — трансформация через восприятие, а не через математику пикселя. Apple, например, создаёт для каждого фирменного цвета минимум два самостоятельных значения — для светлой и тёмной темы, — и иногда сдвигает не только яркость, но и сам оттенок (hue). Их голубой в светлом режиме отличается от тёмного в значении, но критично для читаемости и ощущения "того же" цвета.
| Подход | Что делают | Результат |
|---|---|---|
| Инверсия цвета | Меняют светлое на тёмное по формуле 255-x | Кислотные, "выжигающие" оттенки, потеря идентичности бренда |
| Простое затемнение/высветление | Двигают только lightness, оставляя hue и saturation | Цвет тускнеет или "грязнится", теряет статусность |
| Пересборка через восприятие (Apple-подход) | Меняют lightness, saturation и слегка hue отдельно для каждой темы | Цвет ощущается "тем же", но комфортен для глаз в обеих средах |
Главное правило: на тёмном фоне яркие фирменные цвета нужно делать менее насыщенными, а не просто темнее. Насыщенный акцентный цвет, который отлично работает на белом, при переносе на тёмный фон требует снижения насыщенности на 10–20% — иначе он будет "кричать" и создавать визуальный шум. При этом яркость (lightness) часто нужно, наоборот, слегка поднять, чтобы цвет не тонул на тёмном фоне и оставался читаемым.
Алгоритм трансформации палитры бренда выглядит так:
Логотип и ключевые фирменные акценты стоит адаптировать отдельно от служебной палитры интерфейса: если лого построено на насыщенном цвете, для тёмного фона часто нужна альтернативная версия с пониженной насыщенностью и повышенной светлотой, иначе он будет визуально "прыгать" на экране и отвлекать от контента.
В тёмной теме работает принцип "поверхности приподнимаются светом, а не тенью" — чем выше элемент в визуальной иерархии (карточка над фоном, модальное окно над карточкой), тем светлее его поверхность, а не темнее, как в светлой теме. Это противоположная логика, и именно на ней спотыкаются дизайнеры, привыкшие мыслить в парадигме теней.
Отдельная система нужна для прозрачности текста — она задаёт зрительный приоритет без введения новых цветов:
И ещё одно практическое правило по фону: не берите чистый чёрный #000000 и чистый белый #FFFFFF. Комбинация фона #121212–#1A1A1A с текстом #E0E0E0–#F0F0F0 даёт контраст около 15:1 — этого более чем достаточно для читаемости, но без "ореола" и выжигания на OLED-экранах, которые дают чистый чёрный.
Глазами контраст оценить нельзя надёжно — восприятие яркости нелинейно и зависит от окружающих цветов, освещения монитора и даже усталости смотрящего. Зелёный, который прекрасно читается на белом фоне, на чёрном может не дотягивать до нормы WCAG — 4,5:1 для обычного текста и 3:1 для крупного текста и интерактивных элементов. Поэтому каждую пару "текст-фон" нужно аудировать отдельно для каждой темы, а не переносить результат проверки светлой темы на тёмную по аналогии.
| Инструмент | Для чего |
|---|---|
| WebAIM Contrast Checker | Быстрая проверка пары цветов на соответствие WCAG AA/AAA |
| Figma плагин Contrast / Stark | Проверка контраста прямо в макете, на этапе дизайна |
| Figma Variables + режимы | Хранение семантических токенов и переключение между темами без правки компонентов |
| Chrome DevTools (Accessibility panel) | Проверка реального контраста на живом сайте, с учётом рендеринга |
Хорошее практическое правило для быстрой самопроверки без инструментов: между оттенком текста и оттенком фона должно быть минимум 4 шага в шкале палитры — например, если фон взят как slate-100, текст должен быть не светлее slate-700. Если разница меньше — контраста недостаточно, даже если "на глаз" выглядит нормально.
Большинство провалов тёмной темы сводятся к нескольким повторяющимся промахам:
Решение всех пяти проблем одно — строить палитру не как набор фиксированных hex-кодов, а как систему токенов с осмысленными именами (--color-surface, --color-text-primary), где под капотом для каждой темы лежит своё, отдельно откалиброванное значение цвета. Это дороже на этапе проектирования, но именно такой подход даёт бренду возможность одинаково узнаваться и одинаково хорошо читаться независимо от того, в какой теме открыт продукт.
Глаз воспринимает один и тот же цвет по-разному на светлом и тёмном фоне — это не метафора, а физиология зрения. Насыщенный цвет, который на белом фоне читается как спокойный и статусный, на чёрном начинает вибрировать и вызывать зрительное утомление за счёт эффекта одновременного контраста. Поэтому механическая инверсия (белый→чёрный, тёмно-синий→светло-синий через простой сдвиг HSL) ломает саму идею бренда: цвет должен вызывать одинаковую эмоцию в обеих темах, а не одинаковый код.
Правильная логика — трансформация через восприятие, а не через математику пикселя. Apple, например, создаёт для каждого фирменного цвета минимум два самостоятельных значения — для светлой и тёмной темы, — и иногда сдвигает не только яркость, но и сам оттенок (hue). Их голубой в светлом режиме отличается от тёмного в значении, но критично для читаемости и ощущения "того же" цвета.
| Подход | Что делают | Результат |
|---|---|---|
| Инверсия цвета | Меняют светлое на тёмное по формуле 255-x | Кислотные, "выжигающие" оттенки, потеря идентичности бренда |
| Простое затемнение/высветление | Двигают только lightness, оставляя hue и saturation | Цвет тускнеет или "грязнится", теряет статусность |
| Пересборка через восприятие (Apple-подход) | Меняют lightness, saturation и слегка hue отдельно для каждой темы | Цвет ощущается "тем же", но комфортен для глаз в обеих средах |
Главное правило: на тёмном фоне яркие фирменные цвета нужно делать менее насыщенными, а не просто темнее. Насыщенный акцентный цвет, который отлично работает на белом, при переносе на тёмный фон требует снижения насыщенности на 10–20% — иначе он будет "кричать" и создавать визуальный шум. При этом яркость (lightness) часто нужно, наоборот, слегка поднять, чтобы цвет не тонул на тёмном фоне и оставался читаемым.
Алгоритм трансформации палитры бренда выглядит так:
Логотип и ключевые фирменные акценты стоит адаптировать отдельно от служебной палитры интерфейса: если лого построено на насыщенном цвете, для тёмного фона часто нужна альтернативная версия с пониженной насыщенностью и повышенной светлотой, иначе он будет визуально "прыгать" на экране и отвлекать от контента.
В тёмной теме работает принцип "поверхности приподнимаются светом, а не тенью" — чем выше элемент в визуальной иерархии (карточка над фоном, модальное окно над карточкой), тем светлее его поверхность, а не темнее, как в светлой теме. Это противоположная логика, и именно на ней спотыкаются дизайнеры, привыкшие мыслить в парадигме теней.
Отдельная система нужна для прозрачности текста — она задаёт зрительный приоритет без введения новых цветов:
И ещё одно практическое правило по фону: не берите чистый чёрный #000000 и чистый белый #FFFFFF. Комбинация фона #121212–#1A1A1A с текстом #E0E0E0–#F0F0F0 даёт контраст около 15:1 — этого более чем достаточно для читаемости, но без "ореола" и выжигания на OLED-экранах, которые дают чистый чёрный.
Глазами контраст оценить нельзя надёжно — восприятие яркости нелинейно и зависит от окружающих цветов, освещения монитора и даже усталости смотрящего. Зелёный, который прекрасно читается на белом фоне, на чёрном может не дотягивать до нормы WCAG — 4,5:1 для обычного текста и 3:1 для крупного текста и интерактивных элементов. Поэтому каждую пару "текст-фон" нужно аудировать отдельно для каждой темы, а не переносить результат проверки светлой темы на тёмную по аналогии.
| Инструмент | Для чего |
|---|---|
| WebAIM Contrast Checker | Быстрая проверка пары цветов на соответствие WCAG AA/AAA |
| Figma плагин Contrast / Stark | Проверка контраста прямо в макете, на этапе дизайна |
| Figma Variables + режимы | Хранение семантических токенов и переключение между темами без правки компонентов |
| Chrome DevTools (Accessibility panel) | Проверка реального контраста на живом сайте, с учётом рендеринга |
Хорошее практическое правило для быстрой самопроверки без инструментов: между оттенком текста и оттенком фона должно быть минимум 4 шага в шкале палитры — например, если фон взят как slate-100, текст должен быть не светлее slate-700. Если разница меньше — контраста недостаточно, даже если "на глаз" выглядит нормально.
Большинство провалов тёмной темы сводятся к нескольким повторяющимся промахам:
Решение всех пяти проблем одно — строить палитру не как набор фиксированных hex-кодов, а как систему токенов с осмысленными именами (--color-surface, --color-text-primary), где под капотом для каждой темы лежит своё, отдельно откалиброванное значение цвета. Это дороже на этапе проектирования, но именно такой подход даёт бренду возможность одинаково узнаваться и одинаково хорошо читаться независимо от того, в какой теме открыт продукт.