- Docs
- /
- Getting Started
- /
- Dark Mode
Getting Started
Dark Mode
Svelora includes built-in dark mode support. All components automatically adapt to the current theme.
Setup
Two things are needed: the `ModeWatcher` component in your layout, and the `@custom-variant` CSS rule.
`src/routes/+layout.svelte`
<script lang="ts">
import './layout.css';
import { ModeWatcher } from 'mode-watcher';
let { children } = $props();
</script>
<ModeWatcher />
{@render children()}`src/routes/layout.css`
@import 'tailwindcss';
@import 'svelora/theme.css';
/* Required for Tailwind CSS 4 dark mode classes */
@custom-variant dark (&:where(.dark, .dark *));Toggle Button
Use `ThemeModeButton` for a ready-to-use theme switcher with animated icons.
<script lang="ts">
import { ThemeModeButton } from 'svelora';
</script>
<ThemeModeButton />
<ThemeModeButton size="sm" variant="outline" />
<ThemeModeButton size="lg" variant="soft" color="primary" />
<ThemeModeButton lightIcon="lucide:sun-medium" darkIcon="lucide:moon-star" />Programmatic Control
Use `mode`, `setMode`, and `toggleMode` to control the theme manually.
<script lang="ts">
import { mode, setMode, toggleMode } from 'mode-watcher';
</script>
<p>Current: {mode.current}</p>
<button onclick={() => setMode('dark')}>Dark</button>
<button onclick={() => setMode('light')}>Light</button>
<button onclick={toggleMode}>Toggle</button>Styling with Dark Mode
You can use Tailwind's `dark:` variant, but Svelora semantic colors usually remove the need for it.
<!-- Tailwind dark: variant -->
<div class="bg-white dark:bg-gray-900">
<p class="text-gray-900 dark:text-white">
This text adapts to the theme.
</p>
</div>
<!-- Svelora semantic colors -->
<div class="bg-surface text-on-surface">
<p class="text-on-surface/60">
Semantic colors handle dark mode for you.
</p>
</div>Why Semantic Colors?
| Approach | Code |
|---|---|
| Manual (verbose) | bg-white dark:bg-gray-900 text-gray-900 dark:text-white |
| Semantic (automatic) | bg-surface text-on-surface |