Skip to content

Tailwind CSS Dark Mode — dark: Variant and Strategy Configuration

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you will learn about Tailwind CSS Dark Mode. We cover key concepts, practical examples, and best practices to help you master this topic.

Tailwind CSS dark mode provides a dark: prefix that applies styles when dark mode is active, supporting both system preference (media Strategy) and manual toggle (class strategy).

What You'll Learn

You will learn how to enable dark mode in the config, use the dark: variant with any utility, configure class strategy for manual toggling, and build dark mode compatible components.

Why It Matters

Dark mode reduces eye strain and saves battery on OLED screens. DodaTech's tools including Doda Browser and Durga Antivirus Pro all support dark mode using Tailwind's dark: variant.

Real-World Use

Durga Antivirus Pro's dashboard uses dark:bg-gray-900 for the background, dark:text-white for text, and dark:border-gray-700 for borders, providing a complete dark theme with minimal code.

flowchart LR
    A[States] --> B[Dark Mode]
    B --> C[media Strategy]
    B --> D[class Strategy]
    B --> E[dark: Variant]
    B --> F[Toggle]
    style B fill:#38bdf8,stroke:#0284c7,color:#fff
    style C fill:#22c55e,stroke:#16a34a,color:#fff

Media Strategy (System Preference)

// tailwind.config.js - dark mode by system preference
module.exports = {
  darkMode: 'media',
  // ...
}
<div class="bg-white dark:bg-gray-900 min-h-screen p-8">
  <div class="max-w-md mx-auto bg-gray-50 dark:bg-gray-800 rounded-xl p-6 shadow-lg">
    <h2 class="text-gray-900 dark:text-white text-xl font-bold">
      System Dark Mode
    </h2>
    <p class="text-gray-600 dark:text-gray-300 mt-2">
      This card follows the system dark mode setting. Try toggling your OS theme.
    </p>
    <div class="mt-4 flex gap-2">
      <span class="bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-3 py-1 rounded-full text-sm">
        Dark mode ready
      </span>
    </div>
  </div>
</div>

Expected output: The card uses light styles by default and dark styles when the user's system dark mode is enabled.

Class Strategy (Manual Toggle)

// tailwind.config.js - manual toggle dark mode
module.exports = {
  darkMode: 'class',
  // ...
}
<!-- Toggle button -->
<button id="darkToggle" class="px-4 py-2 bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-white rounded-lg">
  Toggle Dark Mode
</button>

<script>
  document.getElementById('darkToggle').addEventListener('click', () => {
    document.documentElement.classList.toggle('dark');
  });
</script>

<!-- Content (always renders with dark: variants) -->
<div class="bg-white dark:bg-gray-900 p-8 rounded-lg mt-4">
  <h3 class="text-gray-900 dark:text-white font-bold">Manual Dark Mode</h3>
  <p class="text-gray-600 dark:text-gray-300 mt-2">
    Dark mode toggles when the button is clicked, regardless of system preference.
  </p>
</div>

Expected output: Toggling the button adds/removes the dark class on the html element, switching between light and dark styles.

Dark Mode Card Example

<div class="max-w-md mx-auto rounded-xl overflow-hidden shadow-lg transition-colors duration-200">
  <!-- Card image -->
  <div class="h-48 bg-gradient-to-r from-blue-400 to-purple-500 dark:from-blue-800 dark:to-purple-900"></div>

  <!-- Card body -->
  <div class="p-6 bg-white dark:bg-gray-800 transition-colors">
    <div class="flex items-center justify-between">
      <span class="text-sm text-blue-600 dark:text-blue-400 font-medium">Category</span>
      <span class="text-xs text-gray-400 dark:text-gray-500">3 min read</span>
    </div>

    <h3 class="mt-2 text-xl font-bold text-gray-900 dark:text-white">
      Card Title
    </h3>

    <p class="mt-2 text-gray-600 dark:text-gray-300 text-sm leading-relaxed">
      This card uses dark: variants for background, text, and gradient colors. All colors transition to darker equivalents.
    </p>

    <div class="mt-4 flex items-center gap-2">
      <div class="w-8 h-8 bg-gray-300 dark:bg-gray-600 rounded-full"></div>
      <div>
        <p class="text-sm font-medium text-gray-900 dark:text-white">Author Name</p>
        <p class="text-xs text-gray-400 dark:text-gray-500">Posted June 28</p>
      </div>
    </div>
  </div>
</div>

Expected output: A complete card with image, text, and author section that switches between light and dark color schemes.

Dark Mode Form Elements

<div class="max-w-md mx-auto p-6 bg-white dark:bg-gray-900 rounded-xl transition-colors">
  <h2 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Dark Mode Form</h2>

  <div class="space-y-4">
    <div>
      <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Name</label>
      <input type="text"
             class="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg
                    bg-white dark:bg-gray-800 text-gray-900 dark:text-white
                    placeholder:text-gray-400 dark:placeholder:text-gray-500
                    focus:ring-2 focus:ring-blue-500 focus:border-transparent
                    transition-colors">
    </div>

    <div>
      <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Bio</label>
      <textarea rows="3"
                class="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg
                       bg-white dark:bg-gray-800 text-gray-900 dark:text-white
                       placeholder:text-gray-400 dark:placeholder:text-gray-500
                       focus:ring-2 focus:ring-blue-500 focus:border-transparent
                       transition-colors">Dark mode textarea</textarea>
    </div>

    <label class="flex items-center gap-2">
      <input type="checkbox"
             class="rounded border-gray-300 dark:border-gray-600
                    text-blue-600 dark:text-blue-400
                    bg-white dark:bg-gray-800
                    focus:ring-2 focus:ring-blue-500
                    transition-colors">
      <span class="text-sm text-gray-700 dark:text-gray-300">Remember me</span>
    </label>
  </div>
</div>

Expected output: Form inputs, textareas, and checkboxes with complete dark mode styling including borders, backgrounds, text, placeholders, and focus rings.

Dark Mode with Transitions

<div class="p-6 bg-white dark:bg-gray-900 min-h-screen transition-colors duration-300">
  <h1 class="text-gray-900 dark:text-white transition-colors duration-300">
    Smooth Dark Mode Transitions
  </h1>
  <p class="text-gray-600 dark:text-gray-300 mt-2 transition-colors duration-300">
    Adding transition-colors duration-300 to all themed elements creates a smooth dark mode switch.
  </p>
</div>

Expected output: When dark mode toggles, colors transition smoothly over 300ms instead of snapping instantly.

Common Mistakes

1. Not Adding dark Mode to the Config

Without darkMode: 'class' or darkMode: 'media' in the config, the dark: variant produces no styles.

2. Inconsistent Dark Color Choices

Using dark:bg-gray-900 for backgrounds and dark:bg-gray-700 for cards creates insufficient contrast. Stick to a consistent dark palette.

3. Forgetting dark: on Interactive States

dark:hover:bg-gray-700 and dark:focus:ring-blue-400 ensure interactive states work in dark mode too.

4. Not Handling Images in Dark Mode

Images with white backgrounds look harsh in dark mode. Add dark:opacity-80 or use CSS filters for images.

5. Ignoring Color Contrast in Dark Mode

What is accessible in light mode may fail contrast requirements in dark mode. Test both themes with a contrast checker.

Practice Questions

  1. What are the two dark mode strategies? media (follows system preference) and class (manual toggle via the dark class).

  2. How do you enable dark mode with manual toggle? darkMode: 'class' in tailwind.config.js, then toggle dark class on the html element.

  3. How do you style a button in dark mode? Use dark: variants: dark:bg-gray-800 dark:text-white dark:border-gray-600.

  4. Can dark mode be responsive? Yes: dark:md:bg-gray-900 applies dark background on medium screens and above in dark mode.

  5. How do you smooth the dark mode transition? Add transition-colors duration-300 to themed elements.

Challenge

Build a complete dark mode compatible page: navbar with dark:bg-gray-900, hero section with dark gradient, card grid with dark backgrounds, form with dark inputs, and footer. Toggle dark mode with a button.

FAQ

Does dark mode work with Tailwind v3 JIT?

Yes. The JIT engine generates dark: variants on demand, keeping CSS size minimal.

Can I use dark mode with CSS variables?

Yes. Combine dark: variants with CSS variable colors for advanced theming.

How do I persist dark mode preference?

Save the preference in localStorage and apply the dark class on page load with JavaScript.

Does dark mode affect Tailwind's performance?

Negligible. The JIT engine only generates used dark variants.

Can I have multiple color themes beyond dark/light?

Yes. Use class-based strategies with custom class names like theme-red, theme-blue.

Mini Project

Build a dark mode toggle component: sun/moon icon, button with hover/active states, localStorage persistence, and system preference detection. Apply dark: variants to a full page layout.

What's Next

Now master Custom Fonts for typography customization. Then learn Custom Colors for brand-specific theming.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro