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:

  1. Prefix System: Use the dark: prefix before any utility class to create dark mode variants
  2. CSS Scoping: Dark mode utilities are automatically scoped under a .dark class
  3. Automatic Generation: The framework automatically generates dark mode CSS when it encounters dark: prefixed classes
  4. Manual Activation: Dark mode styles are activated by adding the .dark class 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

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>