Dark Mode Support
Twigwind provides comprehensive dark mode support through the dark: prefix, allowing you to create beautiful interfaces that adapt to user preferences.
How Dark Mode Works
Twigwind's dark mode system works by:
- Prefix System: Use the
dark:prefix before any utility class to create dark mode variants - CSS Scoping: Dark mode utilities are automatically scoped under a
.darkclass - Automatic Generation: The framework automatically generates dark mode CSS when it encounters
dark:prefixed classes - Manual Activation: Dark mode styles are activated by adding the
.darkclass to a parent element (usually<html>or<body>)
Basic Dark Mode Syntax
Apply dark mode variants using the dark: prefix:
Syntax
<!-- Light mode: white background, dark text -->
<!-- Dark mode: dark background, light text -->
<div class="bg-white dark:bg-black color-black dark:color-white p-20">
<h2>Adaptive Content</h2>
<p>This content adapts to light and dark modes</p>
</div>
Enabling Dark Mode
To enable dark mode utilities, use the dark: prefix before any utility class. The dark mode styles will be applied when the .dark class is present on a parent element (typically <html> or <body>):
HTML Setup
<!-- Light mode (default) -->
<html lang="en">
<body>
<div class="bg-white dark:bg-gray-900">Content</div>
</body>
</html>
<!-- Dark mode enabled -->
<html lang="en" class="dark">
<body>
<div class="bg-white dark:bg-gray-900">Content</div>
</body>
</html>
Dark Mode Toggle Implementation
Create a toggle button to switch between light and dark modes:
JavaScript Toggle
<!-- Toggle Button -->
<button id="dark-mode-toggle" class="bg-blue color-white dark:bg-yellow dark:color-black p-10 border-radius-6px">
<span class="dark-mode-text">🌙 Dark Mode</span>
</button>
<script>
const toggleBtn = document.getElementById('dark-mode-toggle');
const html = document.documentElement;
const toggleText = document.querySelector('.dark-mode-text');
// Check for saved theme preference or default to light
const currentTheme = localStorage.getItem('theme') || 'light';
if (currentTheme === 'dark') {
html.classList.add('dark');
toggleText.textContent = '☀️ Light Mode';
}
toggleBtn.addEventListener('click', () => {
html.classList.toggle('dark');
if (html.classList.contains('dark')) {
localStorage.setItem('theme', 'dark');
toggleText.textContent = '☀️ Light Mode';
} else {
localStorage.setItem('theme', 'light');
toggleText.textContent = '🌙 Dark Mode';
}
// Re-apply Twigwind styles for new theme
document.querySelectorAll("[class]").forEach(el => Twigwind.twApply(el));
Twigwind.twInject();
});
</script>
Common Dark Mode Patterns
Here are common patterns for implementing dark mode in your designs:
Background & Text Colors
Example
<!-- Page background -->
<body class="bg-white dark:bg-black">
<!-- Card components -->
<div class="bg-white dark:bg-blueGrey color-black dark:color-white p-20 border-radius-8px">
<h3 class="color-blue dark:color-lightBlue">Card Title</h3>
<p class="color-blueGrey dark:color-white">Card content</p>
</div>
<!-- Navigation -->
<nav class="bg-lightBlue dark:bg-black p-15">
<a href="#" class="color-blue dark:color-white hover:color-purple dark:hover:color-lightBlue">Link</a>
</nav>
Borders & Shadows
Example
<!-- Adaptive borders -->
<div class="border-2 border-lightBlue dark:border-blueGrey p-20">
Content with adaptive borders
</div>
<!-- Adaptive shadows -->
<div class="shadow-lg dark:shadow-2xl bg-white dark:bg-blueGrey p-20">
Card with adaptive shadow
</div>
Interactive Elements
Example
<!-- Buttons -->
<button class="bg-blue dark:bg-purple color-white p-12 border-radius-6px hover:bg-lightBlue dark:hover:bg-deepPurple transition:all_0.2s_ease">
Adaptive Button
</button>
<!-- Form inputs -->
<input type="text" class="bg-white dark:bg-blueGrey color-black dark:color-white border-2 border-lightBlue dark:border-white p-10 border-radius-4px" placeholder="Enter text">
System Preference Detection
Automatically detect user's system preference for dark mode:
CSS Media Query Detection
// Detect system preference
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
// Apply theme based on system preference (if no saved preference)
const savedTheme = localStorage.getItem('theme');
if (!savedTheme) {
if (prefersDark) {
document.documentElement.classList.add('dark');
localStorage.setItem('theme', 'dark');
}
}
// Listen for system preference changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!localStorage.getItem('theme')) {
if (e.matches) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
// Re-apply Twigwind styles
document.querySelectorAll("[class]").forEach(el => Twigwind.twApply(el));
Twigwind.twInject();
}
});
Dark Mode Best Practices
- Consistent Contrast: Ensure sufficient contrast in both light and dark modes
- Semantic Colors: Use semantic color names that work in both themes
- Test Both Modes: Always test your interface in both light and dark modes
- Gradual Transitions: Use transitions for smooth theme switching
- Save Preferences: Remember user's theme choice in localStorage
- System Integration: Respect system preferences when possible
Complete Dark Mode Example
Full Implementation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dark Mode Example</title>
<script src="../src/css.js"></script>
<link rel="stylesheet" href="../src/css.css">
</head>
<body class="bg-white dark:bg-black color-black dark:color-white transition:all_0.3s_ease">
<header class="bg-lightBlue dark:bg-blueGrey p-20">
<div class="flex:row-left-center">
<h1 class="color-blue dark:color-white">My App</h1>
<button id="theme-toggle" class="ml-auto bg-blue dark:bg-yellow color-white dark:color-black p-8 border-radius-4px">
🌙 Toggle Theme
</button>
</div>
</header>
<main class="p-30">
<div class="bg-white dark:bg-blueGrey p-20 border-radius-8px shadow-lg dark:shadow-2xl">
<h2 class="color-purple dark:color-lightBlue mb-15">Welcome</h2>
<p class="color-blueGrey dark:color-white mb-20">This content adapts to your theme preference.</p>
<button class="bg-purple dark:bg-teal color-white p-12 border-radius-6px hover:bg-deepPurple dark:hover:bg-green transition:all_0.2s_ease">
Get Started
</button>
</div>
</main>
<script>
// Initialize Twigwind
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll("[class]").forEach(el => Twigwind.twApply(el));
Twigwind.twInject();
});
// Theme toggle functionality
const themeToggle = document.getElementById('theme-toggle');
const html = document.documentElement;
// Load saved theme
const savedTheme = localStorage.getItem('theme') ||
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
if (savedTheme === 'dark') {
html.classList.add('dark');
themeToggle.textContent = '☀️ Toggle Theme';
}
themeToggle.addEventListener('click', () => {
html.classList.toggle('dark');
const isDark = html.classList.contains('dark');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
themeToggle.textContent = isDark ? '☀️ Toggle Theme' : '🌙 Toggle Theme';
// Re-apply Twigwind for theme change
document.querySelectorAll("[class]").forEach(el => Twigwind.twApply(el));
Twigwind.twInject();
});
</script>
</body>
</html>