В SvelteKit реализация темной темы строится вокруг реактивного управления состоянием и динамического применения стилей. Основной подход заключается в использовании store для хранения текущей темы и условного применения CSS-классов или CSS-переменных в зависимости от значения store.
writable store для темыДля управления темой создаётся writable store из
svelte/store:
import { writable } from 'svelte/store';
export const theme = writable('light');
theme будет хранить текущее состояние темы:
'light' или 'dark'.
Чтобы синхронизировать тему с локальным хранилищем и сохранять выбор
пользователя между сессиями, используется localStorage:
theme.subscribe(value => {
localStorage.setItem('theme', value);
});
При инициализации приложения можно проверять наличие сохранённой темы:
if (localStorage.getItem('theme')) {
theme.set(localStorage.getItem('theme'));
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
theme.set('dark');
}
Наиболее удобный способ — добавление CSS-класса на корневой элемент
<html> или <body>:
theme.subscribe(value => {
document.documentElement.classList.toggle('dark', value === 'dark');
});
В CSS создаются соответствующие стили:
:root {
--background-color: #ffffff;
--text-color: #000000;
}
.dark {
--background-color: #121212;
--text-color: #e0e0e0;
}
body {
background-color: var(--background-color);
color: var(--text-color);
transition: background-color 0.3s ease, color 0.3s ease;
}
Использование CSS-переменных позволяет легко масштабировать тему на все компоненты интерфейса и быстро менять цвета.
Большинство UI-библиотек для SvelteKit поддерживают динамическую передачу классов или стилей. Например, при использовании компонентов типа Button, Card, Modal, достаточно передавать тему через пропсы или классы:
<Button class:dark={$theme === 'dark'}>
Кнопка
</Button>
Или через глобальные стили:
.dark .button {
background-color: #1f1f1f;
color: #f5f5f5;
}
Для переключения темы создаётся компонент-кнопка:
<script>
import { theme } from '../stores/theme.js';
const toggleTheme = () => {
theme.update(current => current === 'light' ? 'dark' : 'light');
};
</script>
<button on:click={toggleTheme}>
Переключить тему
</button>
Состояние темы автоматически обновляется через store, и все подписанные компоненты меняют внешний вид.
SvelteKit поддерживает server-side rendering (SSR), поэтому важно учитывать начальное значение темы на сервере. Для этого создаются hooks или используется layout load function, чтобы на сервере определить предпочтение пользователя:
export const load = async ({ cookies }) => {
const theme = cookies.get('theme') || 'light';
return { theme };
};
На клиенте store инициализируется полученным значением:
theme.set(data.theme);
При использовании UI-библиотек вроде Svelte Material UI, Flowbite Svelte или Shadcn UI:
class и
style props, что позволяет применять тёмную тему через
классы.Для улучшения UX рекомендуется добавлять переходы при смене темы:
* {
transition: background-color 0.3s ease, color 0.3s ease;
}
Это позволяет избежать резкой смены цветов и делает интерфейс более приятным.
sessionStorage или через cookie для SSR
и синхронизации между устройствами.Эта схема позволяет построить масштабируемую, реактивную и удобную систему Dark Mode в проектах на SvelteKit с использованием UI-библиотек.