
Привет, на связи Виктор Степанов, лид одной из core-команд GitVerse. Сегодня хочу поговорить о важном аспекте нашей платформы — пользовательском опыте. А именно о том, как мы разрабатывали тёмную тему для GitVerse. Это был не просто косметический апгрейд, а полноценный инженерно-дизайнерский проект, в котором переплелись эргономика, технические ограничения и, конечно, ожидания пользователей.
Зачем вообще нужна тёмная тема?
Если вы хоть раз работали в редакторе кода с 22:00 до 4:00, то наверняка знаете, о чём я говорю. Слишком яркий экран в тёмной комнате — это не просто дискомфорт, это усталость глаз, головные боли и, в конце концов, снижение продуктивности. Тёмная тема — не просто модный тренд, а ответ на реальную потребность разработчиков, аналитиков, админов и всех, кто проводит за экраном большую часть своего рабочего времени.
Исторически светлые интерфейсы доминировали не просто так, они были прямым продолжением физического мира. Ещё с XIX века, когда типография и офисная работа строились вокруг белой бумаги с чёрными чернилами, у нас сформировалась визуальная привычка: светлый фон + тёмный текст = читаемость, порядок, профессионализм. Первые компьютерные интерфейсы, особенно в 1970-80-х, во многом повторяли этот шаблон. Достаточно вспомнить текстовые терминалы вроде VT100: белый текст на чёрном фоне? нет, чаще наоборот: чёрный текст на белом или светло-сером. Даже в ранних версиях Mac OS и Windows цветовая схема была максимально приближена к бумажному листу.
Но тёмные интерфейсы тоже были с нами с самого начала, просто в другой нише. Военные системы, диспетчерские панели, телекоммуникационные станции — там, где операторы работали в условиях низкой освещённости, использовали тёмные фоны с зелёным или оранжевым текстом. Это было не модно, а функционально: меньше бликов, меньше усталости глаз.
Переломный момент наступил в 2000-х, когда появились первые массовые IDE с поддержкой тем. Например, TextMate для macOS, выпущенная в 2004 году, стала одной из первых сред, где тёмная тема воспринималась как часть идентичности разработчика. А в 2006 году релиз Black IDE Theme для Eclipse произвёл настоящий фурор в сообществе: люди впервые осознали, что IDE может выглядеть не как офисный документ.
Но настоящий прорыв случился позже, с развитием OLED- и AMOLED-экранов, особенно в смартфонах и ноутбуках конца 2010-х. Благодаря им чёрный цвет перестал быть просто цветом — он стал отсутствием света. Пиксели гасли, экономя заряд батареи, а контрастность взлетала. Apple внедрила системную тёмную тему в macOS Mojave в 2018 году, Google — в Android 10 в том же году. И с этого момента тёмная тема перестала быть нишевой опцией, она превратилась в ожидаемый стандарт.
Сегодня пользователи не просто хотят тёмную тему. Они ожидают получить её сразу. И если её нет, это воспринимается не как доработка на будущее, а как упущение, почти как баг. Особенно в продуктах для разработчиков. Потому что, когда ты сидишь за кодом в два часа ночи, разница между комфортным интерфейсом и глазной мигренью — в паре десятков оттенков чёрного.
Как мы делали тёмную тему: технические решения и выбор архитектуры
Перед нами стояла задача: реализовать тёмную тему, которая не просто переключает цвета, а обеспечивает согласованность, поддерживаемость и расширяемость. При этом мы активно используем Tailwind CSS — значит, подход должен быть не только визуально точным, но и органично вписываться в наш инструментарий.
Мы рассмотрели несколько стратегий, которые сегодня применяются в современных веб-приложениях. Вот основные из них:
Сlass-based dark mode (подход Tailwind по умолчанию)
Tailwind из коробки поддерживает модификатор dark:*, который по умолчанию активируется через медиа-запрос prefers-color-scheme: dark. Это просто, не требует JS и отлично работает для системных настроек.
Достоинства:
нулевая настройка;
поддержка системной темы «из коробки»;
лёгкая интеграция.
Недостатки:
максимально хардкодная привязка темы к компонентам;
жёсткая привязка к системным настройкам;
сложность применения в кастомных темах (например, «deep blue» или «solarized»).
Class-driven dark mode (кастомизация через @custom-variant)
Tailwind позволяет переопределить поведение dark:*, например, активировать его не по prefers-color-scheme, а по наличию класса .dark в <html>:
// tailwind.config.js
module.exports = {
darkMode: 'class' // вместо 'media'
}
<html class="dark">
<body>
<div class="bg-white dark:bg-gray-800">...</div>
</body>
</html>
Достоинства:
полный контроль — можно переключать тему через интерфейс;
поддержка localStorage, SSR, серверной персистентности;
совместимость с существующими
dark:*-утилитами.
Недостатки:
всё ещё жёсткая бинарность: светлая или тёмная;
цвета зашиты в классы, сложно менять палитру динамически.
Data-атрибут и кастомный селектор
Можно пойти дальше и использовать data-theme, например:
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
<html data-theme="dark">
Это даёт гибкость в именовании и позволяет легко управлять темой через JS, не смешивая стили и поведение.
Семантическая темизация через CSS-переменные
Мы выбрали гибридный подход:
используем в Tailwind
darkMode: 'class';но не задаём цвета напрямую через
dark:bg-gray-800;вместо этого — семантические CSS-переменные, которые сами меняются в зависимости от темы.
Как это работает:
-
В
:rootи[data-theme="dark"]мы определяем единые семантические переменные::root { --bg-base: #ffffff; --bg-primary: #eaeef1; --bg-secondary: #f0f3f5; } [data-theme="dark"] { --bg-base: #1f212b; --bg-primary: #4c5567; --bg-secondary: #252832; } -
В Tailwind мы настраиваем
theme.extend.colorsтак, чтобы использовать эти переменные:theme: { extend: { colors: { surface: 'rgb(var(--bg-surface))', 'text-primary': 'rgb(var(--text-primary))', 'border-muted': 'rgb(var(--border-muted))', accent: 'rgb(var(--control-accent))', } } } -
В разметке используем утилиты с семантическими именами:
<div class="bg-surface text-text-primary border border-border-muted">
Почему именно так?
Есть поддержка ручного переключения: класс
darkилиdata-theme="dark"управляется через React-контекст и сохраняется вlocalStorage.Динамическая смена темы без перезагрузки.
Семантическая чистота: компоненты интерфейса не зависят от конкретного вида фона (светлого или тёмного), а ориентируются исключительно на свою роль в дизайне («фон», «текст»). Поэтому, независимо от выбранной цветовой схемы, компонент остаётся семантически правильным и адаптивным, автоматически применяя нужные стили без изменения своей внутренней структуры.
Масштабируемость: добавить новую тему (например,
data-theme="solarized") просто, нужно лишь переопределить переменные.Совместимость с Tailwind: все утилиты работают как обычно, но цвета динамические.
Что это дает в перспективе? Это основа для пользовательских тем. В будущем мы сможем:
позволить пользователям выбирать из нескольких предустановленных тем;
внедрить кастомизатор цветов;
поддерживать темы на уровне организации или проекта.
Тёмная тема — это не конечная цель, а шаг к персонализированному интерфейсу, в котором каждый разработчик чувствует себя комфортно в любое время суток и с любым вкусом в цветах.
Посмотреть своими глазами
Хотите увидеть, как это работает? Заходите на gitverse.ru, входите в свой аккаунт и в настройках профиля выберите нужную тему. По умолчанию используется светлая тема, но вы можете в любой момент переключиться на тёмную — как вручную, так и настроив автоматическое переключение по системным предпочтениям. Да, поддержка prefers-color-scheme уже реализована: если ваша ОС включила тёмный режим, то GitVerse адаптируется автоматически, без лишних кликов.
А впереди — новые горизонты. Уже сейчас мы прорабатываем поддержку дополнительных цветовых схем, например, «сумеречной» или «минималистичной» — и не исключаем появление пользовательских тем, которые можно будет создавать и делиться ими внутри команды или сообщества.
Тёмная тема — это не просто «инверсия цветов». Это про заботу о пользователе, про внимание к деталям и про то, что даже самые, казалось бы, простые вещи могут быть продуманы до мелочей. Как и всё в GitVerse.
Следите за обновлениями. Всё самое тёмное — уже позади.