Skip to content

Dark mode

The Dark mode component provides a toggle for switching between light and dark color schemes. It uses system preferences, persists user choices, and follows accessibility best practices. It also exposes a global JavaScript API for programmatic control.

  • Website theming
  • User interface customization
  • Reducing eye strain in low-light conditions
  • Respecting user system preferences
  • Battery saving on OLED displays
  • Command palette / launcher integration

Click the toggle below to switch between light and dark mode:

Try using keyboard navigation (Tab + Enter/Space) to toggle!

Learn how to implement the DarkMode component in your project, from basic usage to advanced configurations.

---
import { DarkMode } from 'accessible-astro-components'
---
<!-- Default with system preference (auto mode) -->
<DarkMode />
<!-- Start with dark mode as default -->
<DarkMode initialMode="dark">
<Icon name="ion:sunny" slot="light" />
<Icon name="ion:moon" slot="dark" />
</DarkMode>
<!-- Start with light mode as default -->
<DarkMode initialMode="light">
<Icon name="ion:sunny" slot="light" />
<Icon name="ion:moon" slot="dark" />
</DarkMode>
<!-- With custom icons -->
<DarkMode>
<Icon name="ion:bulb" slot="light" />
<Icon name="ion:bulb-outline" slot="dark" />
</DarkMode>

The DarkMode component exposes a global window.darkMode API for programmatic control. This is useful for integrating with command palettes, launchers, or other UI elements.

// Toggle dark mode
window.darkMode.toggle()
// Enable dark mode
window.darkMode.enable()
// Disable dark mode
window.darkMode.disable()
// Check if dark mode is enabled
window.darkMode.isEnabled() // returns boolean

The component dispatches a darkmode:change custom event when the mode changes:

document.addEventListener('darkmode:change', (e) => {
console.log('Dark mode enabled:', e.detail.enabled)
})

The component automatically listens for launcher:action events with action: 'toggle-dark-mode', making it compatible with the Accessible Astro Launcher out of the box.

Configure the DarkMode component using these available props to customize its behavior and appearance.

PropTypeDefaultDescription
initialMode'light' | 'dark' | 'auto''auto'Sets the initial color scheme mode for first-time visitors (user preference in localStorage takes precedence)
labelstring'Toggle Dark Mode'Accessible label for the toggle button
classstring''Additional CSS classes to apply

The DarkMode component supports named slots for customizing the icons displayed in light and dark modes.

SlotDescription
lightIcon or content to display when in light mode
darkIcon or content to display when in dark mode

Accessibility isn’t an afterthought - it’s built into the core of this component through semantic HTML elements and proper image handling. The DarkMode component is built with accessibility in mind:

  • Uses semantic button element
  • Proper ARIA attributes (aria-pressed, aria-label)
  • Maintains focus states
  • Persists across page loads using localStorage

Make the DarkMode component your own with custom styling while maintaining its accessibility features.

/* Option 1: Using :global() in your style block */
<style>
:global(.darkmode-toggle) {
font-size: 1.125rem;
color: light-dark(hsl(215 8% 45%), hsl(215 8% 65%));
}
:global(.darkmode-toggle:hover) {
color: light-dark(hsl(215 25% 27%), hsl(215 25% 89%));
}
/* Dark mode styles applied to html element */
:global(.darkmode) {
color-scheme: dark;
background: hsl(0 0% 10%);
color: hsl(0 0% 100%);
}
</style>
/* Option 2: Using is:global on the style tag */
<style is:global>
.darkmode-toggle {
font-size: 1.125rem;
color: light-dark(hsl(215 8% 45%), hsl(215 8% 65%));
}
.darkmode-toggle:hover {
color: light-dark(hsl(215 25% 27%), hsl(215 25% 89%));
}
/* Dark mode styles applied to html element */
.darkmode {
color-scheme: dark;
background: hsl(0 0% 10%);
color: hsl(0 0% 100%);
}
</style>

See the DarkMode component in action with these practical examples demonstrating different variants and styling options.