Тёмная тема в Vue — CSS-переменные и LocalStorage
TL;DR
Технически простое и надёжное решение: используйте CSS-переменные для палитры и привязывайте переключатель к атрибуту data-theme на корневом элементе. Сохраняйте выбор пользователя в LocalStorage и включайте плавный переход через CSS. В статье — пошаговая реализация, альтернативы, чек-листы и критерии приёмки.

Внедрение тёмных тем в веб-приложения перестало быть «опцией» и превратилось в практическую необходимость. Пользователи ожидают возможность переключаться между светлой и тёмной темой по эстетическим и эргономическим причинам.
Тёмные темы применяют более тёмную палитру интерфейса, что снижает нагрузку на глаза в условиях низкой освещённости. На устройствах с OLED/AMOLED это также может помочь экономить заряд батареи. Эти преимущества делают обоснованным предложение пользователю переключать тему.
Настройка тестового приложения
Для наглядной реализации создайте простое Vue-приложение. От терминала выполните:
npm init vue@latestЭта команда установит пакет create-vue и проведёт инициализацию проекта. Для целей этого руководства не обязательно выбирать дополнительные фичи.
Добавьте в файл src/App.vue следующий шаблон (HTML):
Welcome to My Vue App
This is a simple Vue app with some text and styles.
Styled Text
В этом примере нет блока
Ключевые моменты:
- ref из Vue обеспечивает реактивность переменной darkMode.
- LocalStorage используется для долговременного хранения выбора пользователя.
- toggleDarkMode переключает флаг и сохраняет значение.
Применение тёмной темы в шаблоне и тестирование
Измените шаблон в App.vue, чтобы привязать атрибут data-theme к состоянию darkMode и добавить кнопку переключения:
Welcome to My Vue App
This is a simple Vue app with some text and styles.
Styled Text
Запустите приложение командой:
npm run devВы должны увидеть базовый интерфейс. При нажатии на кнопку тема будет переключаться.
Дополнительные улучшения и рекомендации по UX
- Добавьте анимацию иконки (солнышко/луна) для понятного визуального сигнала.
- Поддерживайте системный предпочтительный режим (prefers-color-scheme) как значение по умолчанию, если LocalStorage пуст:
const systemPrefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;- Обновляйте aria-атрибуты для доступности (aria-pressed, label для кнопки).
- Если у вас много компонентов, считайте переменные темы глобальной темой (CSS-переменные на :root) вместо инлайновых стилей.
Альтернативные подходы
- UI-библиотеки с поддержкой тем
- Использовать Vuetify, Quasar, Tailwind CSS (с плагином dark) или другие, если проект уже их применяет.
- Плюсы: готовые темы, консистентность, больше компонентов.
- Минусы: размер бандла, зависимость от внешней библиотеки.
- CSS-классы вместо переменных
- Менять класс (например .theme-dark) на body и иметь отдельный набор стилей.
- Подходит когда переменные использовать невозможно, но сложнее поддерживать множество переопределений.
- CSS-in-JS
- Темизация через библиотеку стилей в JS (emotion, styled-components).
- Удобно в компонентных системах, но добавляет runtime-стоимость.
Когда это может не подойти
- Приложение ограничено сторонней темой/шаблоном, где переопределить цвета тяжело.
- Нужны тонкие оптимизации для OLED, и вы хотите контролировать только конкретные элементы.
- Требуется централизованная серверная настройка темы (напр., тема привязана к учётной записи и синхронизируется между устройствами) — нужно хранить настройку в базе, а не только в LocalStorage.
Модель принятия решений (какую стратегию выбрать)
- Малый проект, минимальные зависимости: реализуйте CSS-переменные + LocalStorage.
- Большой проект с компонентной библиотекой: используйте тему через провайдер в UI-библиотеке и синхронизацию настроек.
- Нужна синхронизация между устройствами: сохраняйте выбор на сервере, LocalStorage — как кэш.
flowchart TD
A[Пользователь открывает приложение] --> B{Есть настройка в LocalStorage?}
B -- Да --> C[Применить сохранённую тему]
B -- Нет --> D{Системная тема доступна?}
D -- Да --> E[Применить prefers-color-scheme]
D -- Нет --> F[Применить светлую тему по умолчанию]
C --> G[Отобразить UI]
E --> G
F --> G
G --> H[Пользователь меняет тему]
H --> I[Сохранить в LocalStorage и обновить UI]Чек-листы по ролям
Разработчик:
- Центральное место для переменных темы (styles.css или глобальный стиль) создано.
- Логика получения/сохранения настроек реализована.
- Плавные переходы настроены.
- Тесты на переключение темы и сохранение состояния добавлены.
Дизайнер:
- Контраст текст/фон соответствует рекомендациям доступности.
- Цветовые акценты и состояния элементов учтены для обеих тем.
Тестировщик:
- Переключение темы не ломает формы и модальные окна.
- Сохранение предпочте́ния между перезагрузками работает.
- Компоненты сторонних библиотек корректно отображаются.
Критерии приёмки
- При первом открытии: если есть сохранённая настройка в LocalStorage, тема применяется автоматически.
- Если LocalStorage пуст, применяется системная тема (если доступна), иначе — светлая.
- При переключении кнопкой значение persistируется и сохраняется в LocalStorage.
- Переключение темы не вызывает заметных вспышек стиля и происходит с плавным переходом.
- Элементы с контрастом проходят базовые проверки доступности (визуально и с помощью инструментов).
Факты и пояснения
- CSS-переменные работают в современных браузерах и позволяют менять дизайн без перекомпиляции стилей.
- LocalStorage — простое решение для хранения настроек, но не подходит для многопользовательской синхронизации без сервера.
Мини-методология внедрения
- Добавьте в проект глобальный файл стилей с переменными темы.
- Подключите файл в main.js.
- В App.vue реализуйте ref для darkMode и функции get/save/toggle.
- Привяжите :data-theme к корню шаблона.
- Протестируйте переключение и сохранение состояния.
- Улучшайте UX (иконки, системные настройки, анимации).
Глоссарий (1-строчные определения)
- CSS-переменные: динамические значения в CSS, задаются через –имя и используются через var().
- LocalStorage: браузерное хранилище для данных в виде пар ключ/значение, сохраняется между сессиями.
- prefers-color-scheme: медиа-запрос, отражающий системное предпочтение тёмной/светлой темы.
Краткое резюме
Тёмная тема в Vue легко реализуется с помощью CSS-переменных и LocalStorage. Решение масштабируемо: для больших проектов рассмотрите поддержку темы в UI-библиотеке и сохранение настроек на сервере. Обязательно проверьте доступность и UX-поведение при переключении.
Важно
Проверяйте контраст и доступность цветов для каждого компонента. Если планируете синхронизацию настроек между устройствами — храните состояние на сервере, LocalStorage оставьте как локальный кэш.
Похожие материалы
Как подключить HDD Xbox 360 к ПК
Как найти активные onion‑сайты и безопасно пользоваться Tor
Отключение JavaScript в Tor Browser
Удаление Norton и McAfee с Windows
Защитите аккаунты в соцсетях от мошенников