Гид по технологиям

Темная тема в Vue: реализация с CSS‑переменными и LocalStorage

6 min read Frontend Обновлено 09 Jan 2026
Темная тема в Vue с CSS‑переменными и LocalStorage
Темная тема в Vue с CSS‑переменными и LocalStorage

Человек держит логотип CSS3

Внедрение тёмных тем в веб‑приложения перестало быть «дополнением» и стало стандартной опцией интерфейса. Пользователи переключаются между светлой и тёмной темами не только из эстетических соображений, но и по практическим причинам: тёмная тема снижает нагрузку на глаза в условиях низкой освещённости и экономит энергию на экранах OLED/AMOLED.

В этом материале вы найдёте пошаговую инструкцию для Vue‑приложения: от создания тестового приложения до продвинутых практик, учитывающих предпочтения системы, синхронизацию между вкладками, доступность и возможные альтернативы.

Почему имеет смысл добавить тёмную тему

  • Комфорт для пользователя в условиях низкой освещённости.
  • Экономия батареи на OLED/AMOLED устройствах (чёрные пиксели не потребляют энергию).
  • Совместимость с системными настройками (предпочтения пользователя на уровне ОС).
  • Современные ожидания: пользователи ждут опции переключения темы.

Важно: выбор места хранения предпочтений влияет на поведение при обновлении приложения и синхронизации между вкладками.

Настройка тестового приложения

Чтобы воспроизвести примеры, создайте простое Vue‑приложение.

Откройте терминал и выполните:

npm init vue@latest

Эта команда установит последний пакет create-vue и создаст каркас приложения. Для целей этого руководства дополнительные опции (TypeScript, маршрутизация и т.д.) можно не выбирать — примеры работают в минимальной конфигурации.

В файле src/App.vue добавьте стартовый шаблон (мы будем использовать классы для стилизации):



Этот минимальный шаблон пригодится для демонстрации стилей и логики переключения.

Стилизация через CSS‑переменные

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

Создайте файл src/assets/styles.css и добавьте базовые переменные для светлой и тёмной тем.

/* styles.css */
:root {
  --background-color: #ffffff; /* White */
  --text-color: #333333; /* Dark Gray */
  --box-background: #007bff; /* Royal Blue */
  --box-text-color: #ffffff; /* White */
  --toggle-button: #007bff; /* Royal Blue */
}

[data-theme='true'] {
  --background-color: #333333; /* Dark Gray */
  --text-color: #ffffff; /* White */
  --box-background: #000000; /* Black */
  --box-text-color: #ffffff; /* White */
  --toggle-button: #000000; /* Black */
}

* {
  background-color: var(--background-color);
  text-align: center;
  color: var(--text-color);
  padding: 20px;
  font-family: Arial, sans-serif;
  transition: background-color 0.3s, color 0.3s;
}

.header {
  font-size: 24px;
  margin-bottom: 20px;
}

.styled-box {
  background-color: var(--box-background);
  color: var(--box-text-color);
  padding: 10px;
  border-radius: 5px;
  margin: 20px 0;
}

.styled-text {
  font-size: 18px;
  font-weight: bold;
}

.toggle-button {
  background-color: var(--toggle-button);
  color: #fff;
  border: none;
  border-radius: 3px;
  cursor: pointer;
  padding: 5px 10px;
}

Имейте в виду:

  • :root задаёт значения по умолчанию (светлая тема).
  • атрибутный селектор [data-theme=’true’] переопределяет переменные для тёмной темы.
  • переходы (transition) создают гладкую анимацию при переключении тем.

В main.js импортируйте этот файл стилей:

// main.js
import './assets/styles.css'
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

Логика переключения тёмной темы в Vue

Добавьте в App.vue блок скрипта на Composition API. Мы будем хранить флаг darkMode в реактивной ссылке (ref) и синхронизировать его с localStorage.



Ключевые моменты:

  • Мы сначала пытаемся прочитать значение из localStorage. Если его нет, используем системное prefers-color-scheme.
  • При изменении системной настройки (например, пользователь переключил тему в ОС) и если пользователь не задавал своё явное предпочтение, тема обновится автоматически.
  • Используем событие storage для синхронизации между вкладками.
  • Обёртка try/catch исключает ошибку в окружениях, где localStorage недоступен.

Финальный шаблон App.vue с привязкой

Обновим шаблон, чтобы он использовал переменную darkMode и кнопку для переключения.



После запуска npm run dev вы увидите приложение и сможете переключать тему по кнопке.

Вид созданного приложения Vue в светлой теме

Вид приложения Vue в тёмной теме

Дальнейшие улучшения и практические советы

  1. Accessibility (доступность)

    • Проверяйте контрастность текста с фоном по стандарту WCAG (минимум 4.5:1 для основного текста).
    • Избегайте использования только цвета для передачи информации (подчёркивайте или добавляйте иконки).
    • Тестируйте на реальных устройствах и с программами чтения экрана.
  2. Плавные переходы и перформанс

    • Ограничьте анимируемые свойства: лучше менять цвет и фильтры, но не layout‑свойства.
    • Избегайте обработки всех элементов через универсальный селектор, если у вас большое приложение — переключение темы может привести к переработке большого дерева DOM.
  3. Изображения и медиаконтент

    • Тёмная тема может потребовать альтернативных изображений (например, логотипа с белым контуром).
    • Для векторных изображений (SVG) удобнее менять цвет через CSS (fill, stroke).
  4. SSR и гидрация

    • Для серверного рендеринга хранить предпочтение в localStorage нельзя на сервере. Подумайте о cookie или встроенной метке в HTML (например, data-theme на ) при первом рендере.
    • Иначе возможен эффект «мигания» (FOUC) при гидрации на клиенте.
  5. Синхронизация между вкладками

    • Мы уже добавили обработчик storage — это простая и надёжная стратегия.

Альтернативные подходы

  • Класс вместо атрибута: document.documentElement.classList.toggle(‘dark’) и в CSS использовать .dark { –background-color: … }. Класс удобнее при интеграции с фреймворками и утилитами.
  • prefers-color-scheme как единственный источник правды: хорошо для случаев, когда вы не хотите предоставлять пользовательскую настройку.
  • CSS-фреймворки (Tailwind, Vuetify): у многих есть встроенные механизмы тёмной темы — используйте их, если готовы принять зависимость.

Когда один подход не подходит:

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

Мини‑методология: 7 шагов внедрения тёмной темы

  1. Определите набор цветовых переменных (фон, текст, акценты, тени).
  2. Реализуйте CSS‑переменные для светлой и тёмной тем.
  3. Добавьте переключатель в UI и реактивное состояние (Vue ref).
  4. Сохраните выбор в localStorage (или cookie/профиль).
  5. Поддержите prefers-color-scheme и слушайте его изменения.
  6. Тестируйте контрастность и доступность.
  7. Обновите изображения/иконки для обеих тем.

Чеклисты по ролям

Разработчик:

  • Реализовал CSS‑переменные и переключатель.
  • Добавил сохранение в localStorage и синхронизацию между вкладками.
  • Обработал недоступность localStorage.

Дизайнер:

  • Утвердил палитры для обеих тем.
  • Проверил контрастность по WCAG.
  • Подготовил альтернативные логотипы/изображения.

QA:

  • Проверил переключение локально и между вкладками.
  • Проверил поведение при системном переключении темы.
  • Проверил доступность и контрастность.

Критерии приёмки

  • Переключение темы работает и сохраняется между перезагрузками.
  • При отсутствии явного выбора — используется системная настройка.
  • Переключение между вкладками синхронизируется.
  • Контрастность текста соответствует требованиям доступности.
  • Нет заметной подтормаживания при переключении темы на целевых устройствах.

Тестовые сценарии и случаи приёмки

  1. Новый пользователь без сохранённой настройки. Ожидается: тема совпадает с системной настройкой.
  2. Пользователь переключил тему вручную. Ожидается: выбор сохраняется в localStorage и применяется после перезагрузки.
  3. Пользователь сменил тему в другой вкладке. Ожидается: текущая вкладка автоматически применяет новое значение.
  4. LocalStorage недоступен (приватный режим). Ожидается: приложение не падает, тема определяется по prefers-color-scheme.
  5. SSR: начальная загрузка не должна показать «мигание» другой темы дольше допустимого времени.

Полезные сниппеты

  • Быстрый способ применить тему через класс:
const setDark = (isDark) => {
  document.documentElement.classList.toggle('dark', isDark);
};
  • Пример переключателя с aria‑атрибутами для доступности:
  • Запись в cookie для SSR:
// при логине на сервере добавьте cookie: theme=dark или theme=light
// затем на сервере добавьте атрибут data-theme в  перед отправкой

Совместимость и подводные камни

  • Старые браузеры: CSS‑переменные поддерживаются в современных браузерах; для IE потребуется полифилл.
  • LocalStorage может быть отключён пользователем или недоступен в приватном режиме — код должен обрабатывать исключения.
  • SSR: если тема определяется только на клиенте, возможны визуальные артефакты при начальной загрузке.

Конфиденциальность и хранение настроек

LocalStorage хранит только предпочтение темы (true/false). Это не личные данные, однако имейте в виду:

  • Если приложение хранит тему в профиле на сервере, это становится частью персонализированных данных пользователя.
  • При использовании cookie для SSR учитывайте настройки SameSite, secure и срок жизни.

Короткая сводка для соцсетей

Темная тема в Vue: как добавить переключатель с помощью CSS‑переменных, сохранить выбор в localStorage, учесть системные предпочтения и не нарушить доступность.

Итог

Тёмная тема — это не только про внешний вид. Это про удобство, экономию энергии на некоторых устройствах и ожидания пользователей. Простой подход с CSS‑переменными и localStorage покрывает многие сценарии, но для больших приложений стоит учесть SSR, хранение в профиле и доступность. Выберите стратегию (атрибут vs класс, localStorage vs cookie) исходя из архитектуры вашего приложения.

Important: тестируйте на реальных устройствах и с инструментами проверки доступности.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство