Contents

Dark Mode and Theming with Tailwind CSS

Implementing dark mode and theming in Tailwind CSS allows you to provide a better user experience by adapting the design of your application to different lighting conditions and user preferences. Tailwind CSS makes it easy to implement dark mode with its built-in utilities and allows for dynamic theme switching. This guide will cover how to implement dark mode using Tailwind’s dark mode utilities, create a custom theme with both light and dark modes, and switch themes dynamically based on user preference.

Implementing Dark Mode Using Tailwind’s Dark Mode Utilities

Tailwind CSS provides a built-in dark mode feature that you can enable and customize to create a dark theme for your application.

Step 1: Enable Dark Mode in tailwind.config.js

To use Tailwind’s dark mode utilities, you first need to enable dark mode in your tailwind.config.js file. Tailwind offers two main strategies for enabling dark mode: class-based and media-based.

Class-Based Dark Mode (Preferred)

The class-based strategy allows you to toggle dark mode by adding a dark class to the root element of your application.

				
					module.exports = {
  darkMode: 'class', // or 'media' for media-based
  theme: {
    extend: {},
  },
  plugins: [],
}


				
			
  • darkMode: 'class': Enables dark mode using a class-based approach, which gives you more control over when dark mode is applied.
  • darkMode: 'media': Uses the user’s operating system preference (e.g., prefers-color-scheme) to automatically apply dark mode.
Step 2: Use Dark Mode Utilities in Your CSS

Tailwind’s dark mode utilities allow you to apply styles conditionally when dark mode is enabled.

Example: Applying Dark Mode Styles

 
				
					<div class="bg-white text-black dark:bg-gray-800 dark:text-white p-6">
    <h1 class="text-2xl font-bold">Hello, World!</h1>
    <p>This text changes color based on the active theme.</p>
</div>

				
			
  • dark:bg-gray-800: Sets the background color to dark gray when dark mode is active.
  • dark:text-white: Sets the text color to white when dark mode is active.
Step 3: Toggle Dark Mode with JavaScript

If you’re using class-based dark mode, you can toggle dark mode by adding or removing the dark class from the html or body element.

Example: Toggling Dark Mode with JavaScript

				
					<button id="theme-toggle" class="bg-gray-200 dark:bg-gray-700 p-2 rounded">Toggle Theme</button>

<script>
  const themeToggleBtn = document.getElementById('theme-toggle');
  const htmlElement = document.documentElement;

  themeToggleBtn.addEventListener('click', () => {
    if (htmlElement.classList.contains('dark')) {
      htmlElement.classList.remove('dark');
      localStorage.setItem('theme', 'light');
    } else {
      htmlElement.classList.add('dark');
      localStorage.setItem('theme', 'dark');
    }
  });

  // Load the user's theme preference from localStorage
  const savedTheme = localStorage.getItem('theme');
  if (savedTheme === 'dark') {
    htmlElement.classList.add('dark');
  }
</script>


				
			
  • theme-toggle button: Toggles the dark mode class on the root element.
  • localStorage: Saves the user’s theme preference, so it persists across sessions.

Creating a Custom Theme with Light and Dark Modes

Creating a custom theme allows you to define specific colors, fonts, and styles for both light and dark modes, ensuring that your application looks cohesive and polished.

Step 1: Extend the Tailwind Theme

You can extend Tailwind’s default theme to include custom colors, which will be used for both light and dark modes.

Example: Custom Theme with Light and Dark Colors

				
					module.exports = {
  darkMode: 'class',
  theme: {
    extend: {
      colors: {
        primary: {
          light: '#3b82f6',  // Blue for light mode
          dark: '#1e40af',   // Darker blue for dark mode
        },
        background: {
          light: '#ffffff',  // White for light mode
          dark: '#1f2937',   // Dark gray for dark mode
        },
        text: {
          light: '#1f2937',  // Dark gray for light mode
          dark: '#f9fafb',   // Almost white for dark mode
        },
      },
    },
  },
  plugins: [],
}

				
			
Step 2: Apply the Custom Theme in Your HTML

You can now use these custom colors in your HTML, applying them conditionally based on the active mode.

Example: Applying Custom Theme Colors

				
					<div class="bg-background-light text-text-light dark:bg-background-dark dark:text-text-dark p-6">
    <h1 class="text-3xl font-bold text-primary-light dark:text-primary-dark">Custom Themed Heading</h1>
    <p>This content adapts to light and dark modes using the custom theme.</p>
</div>


				
			
  • bg-background-light dark:bg-background-dark: Switches between light and dark background colors based on the mode.
  • text-text-light dark:text-text-dark: Switches between light and dark text colors.

Switching Themes Dynamically Based on User Preference

Switching themes dynamically allows you to respect the user’s preference for light or dark mode, either through their operating system settings or by allowing them to manually toggle between modes.

Step 1: Detect User Preference with prefers-color-scheme

You can detect the user’s preferred color scheme using the prefers-color-scheme media query.

Example: Detecting User Preference

				
					<script>
  const htmlElement = document.documentElement;

  // Check if the user prefers dark mode
  const userPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

  if (userPrefersDark) {
    htmlElement.classList.add('dark');
  } else {
    htmlElement.classList.remove('dark');
  }

  // Optionally, store the user preference in localStorage
  const savedTheme = localStorage.getItem('theme');
  if (savedTheme) {
    htmlElement.classList.toggle('dark', savedTheme === 'dark');
  }
</script>


				
			
  • prefers-color-scheme: dark: Automatically detects the user’s system preference for dark mode.
Step 2: Allow Users to Manually Toggle Themes

In addition to respecting the user’s system preference, you can allow them to manually toggle between light and dark modes.

Example: Theme Toggle with Button

				
					<button id="theme-toggle" class="p-2 bg-gray-200 dark:bg-gray-800 rounded">
    Toggle Theme
</button>

<script>
  const themeToggleBtn = document.getElementById('theme-toggle');
  const htmlElement = document.documentElement;

  themeToggleBtn.addEventListener('click', () => {
    const isDarkMode = htmlElement.classList.toggle('dark');
    localStorage.setItem('theme', isDarkMode ? 'dark' : 'light');
  });

  // Load the saved theme preference
  const savedTheme = localStorage.getItem('theme') || (userPrefersDark ? 'dark' : 'light');
  htmlElement.classList.toggle('dark', savedTheme === 'dark');
</script>


				
			
  • localStorage.setItem('theme', ...): Stores the user’s choice of theme so it persists across sessions.
  • classList.toggle('dark'): Toggles the dark mode class on the root element.

Summary

Tailwind CSS makes it easy to implement dark mode and theming with its built-in utilities and configurable options. By enabling dark mode in tailwind.config.js, you can apply dark mode styles conditionally. Creating a custom theme with light and dark modes ensures a consistent and polished look across your application. Finally, allowing users to switch themes dynamically, either based on their system preferences or through a manual toggle, enhances the user experience and makes your application more versatile. These strategies help you build modern, responsive, and user-friendly applications with Tailwind CSS.