This guide explains how to enable and manage dark mode in a way consistent with Tailwind’s dark-mode documentation.
To control the dark theme using a custom CSS selector instead of the prefers-color-scheme media query, redefine the dark variant to use the desired selector:
@custom-variant dark (&:where(.dark, .dark *), .dark);The .dark class is typically added or removed on the <html> element.
Add this inline script inside the <head> tag to ensure the correct theme is applied before the page renders. This prevents flash issues and respects both the user’s saved preference in localStorage and their system’s prefers-color-scheme setting.
<script>
// On page load or when changing themes, best to add inline in head to avoid FOUC
document.documentElement.classList.toggle(
"dark",
localStorage.theme === "dark" ||
(!("theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches),
);
</script>This script manages switching between light and dark themes. It works by:
.dark class on the <html> elementlocalStorage and restoring it automatically on page loadconst toggleTheme = (theme) => {
const s = document.createElement('style');
s.textContent = '*,*::before,*::after{transition:none!important;animation:none!important}';
document.head.appendChild(s);
const html = document.documentElement;
if (theme === 'dark') html.classList.add('dark');
else html.classList.remove('dark');
requestAnimationFrame(() => requestAnimationFrame(() => s.remove()));
};
document.addEventListener('DOMContentLoaded', () => {
const savedTheme = localStorage.getItem('theme');
const initialTheme = savedTheme ?? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
toggleTheme(initialTheme);
const toggleThemeBtn = document.querySelector('[data-theme-toggle-btn]');
toggleThemeBtn?.addEventListener('click', () => {
const current = localStorage.getItem('theme') ?? initialTheme;
const newTheme = current === 'dark' ? 'light' : 'dark';
localStorage.setItem('theme', newTheme);
toggleTheme(newTheme);
});
});Any preferred markup can be used for toggling icon visibility based on the current state.
<button type="button" data-theme-toggle-btn class="btn btn-circle btn-subtle-neutral">
<svg class="dark:hidden"><!-- moon icon --></svg>
<svg class="hidden dark:block"><!-- sun icon --></svg>
</button>
Hummingbird supports dark mode out of the box, and all components are fully compatible with it. No additional configuration is required to enable dark mode styles.
To apply additional styling specifically for dark mode, use the dark: variant alongside utility classes. This ensures that elements automatically adjust their appearance whenever the .dark class is active.
<div class="bg-subtle text-primary dark:text-secondary">
This content adapts to dark mode
</div>In addition to using the dark: variant, Hummingbird’s theme variables can be directly overridden within a dark scope:
:root, :host {
@variant dark {
--color-primary: var(--color-blue-400);
--color-secondary: var(--color-purple-400);
}
}See all available variables in the Theming section.
Hummingbird includes a predefined set of color variables that automatically adjust for dark mode, eliminating the need for additional dark mode classes. Components can switch to dark mode by adding the .dark class to a parent element.
To enable this behavior, add the custom dark mode variant to the CSS file after importing Tailwind and Hummingbird styles.
@custom-variant dark (&:where(.dark, .dark *), .dark);