Skip to main content

Starwind UI v1.15 is now available! With new prose, sidebar, and more components

Dark Mode

Starwind UI components are designed with dark mode support out of the box. We use the standard Tailwind CSS dark: variant, which relies on a dark class being present on the <html> element.

How it works

Any element with the class dark, or any element inside a parent with the class dark, will use the dark mode styles. Typically, this class is added to the <html> or <body> element to enable dark mode globally.

Implementation

To prevent a Flash of Unstyled Content (FOUC) when a user visits your site, you should place a small script in the <head> of your layout. This script checks for a saved theme preference in localStorage or falls back to the user’s system preference.

Tip

You can find a number of free and advanced production-ready theme toggle components on Starwind Pro.

Theme Initialization

Add the following script to your main layout file (e.g., src/layouts/Layout.astro):

src/layouts/Layout.astro
<head>
<!-- ... other head elements -->
<script is:inline>
function initTheme() {
const colorTheme = localStorage.getItem("colorTheme");
if (!colorTheme) {
// if no color theme yet, use the users preferences
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
document.documentElement.classList.add("dark");
localStorage.setItem("colorTheme", "dark");
} else {
document.documentElement.classList.remove("dark");
localStorage.setItem("colorTheme", "light");
}
} else {
// assign the theme based on the value in local storage
if (colorTheme === "dark") {
document.documentElement.classList.add("dark");
} else if (colorTheme === "light") {
document.documentElement.classList.remove("dark");
} else if (colorTheme === "system") {
// use system preference
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
document.documentElement.classList.toggle("dark", prefersDark);
}
}
}
// runs on initial page load
initTheme();
// runs on view transitions navigation
document.addEventListener("astro:after-swap", initTheme);
</script>
</head>

Info

Starwind UI respects the user’s system preferences by default. If a user hasn’t explicitly chosen a theme on your site, the initTheme script will detect their OS settings using window.matchMedia("(prefers-color-scheme: dark)").

Manual Toggling

To allow users to manually switch between themes, you can create a toggle component that updates localStorage and the <html> class. As a simple starter you can use Starwind UI’s theme-toggle component.

// Example of how to toggle the theme manually
function toggleTheme(newTheme) {
if (newTheme === 'dark') {
document.documentElement.classList.add('dark');
} else if (newTheme === 'light') {
document.documentElement.classList.remove('dark');
} else if (newTheme === 'system') {
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
document.documentElement.classList.toggle('dark', prefersDark);
}
localStorage.setItem('colorTheme', newTheme);
}

Astro View Transitions

If you are using Astro’s View Transitions with <ClientRouter>, the initTheme function needs to be re-run after each navigation. The provided script handles this using the astro:after-swap event listener.