# My Eyes are Burning

There are two types of developers in this world: those who use Light Mode, and those who are wrong. (Just kidding... mostly).

When working on a development project, I knew Dark Mode wasn't just a "nice to have"—it was a requirement. Developers browsing portfolios at 2 AM don't want to be blinded by a white background.

But building a *good* toggle isn't just about swapping colors. You need to:

1. Remember the user's choice (Persistence).
    
2. Respect the Operating System's default preference.
    
3. Avoid the "flash of unstyled content" (FOUC) on refresh.
    

Here is how I implemented a robust Dark Mode toggle using React and Tailwind CSS.

### Step 1: The Tailwind Configuration

By default, Tailwind uses the system settings. But I wanted a manual toggle button. To do this, I had to tell Tailwind to look for a CSS class instead.

In tailwind.config.js:

```bash
module.exports = {
  darkMode: 'class', // 👈 This is the magic line
  content: ["./src/**/*.{js,jsx,ts,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

Now, whenever the parent &lt;html&gt; tag has the class dark, Tailwind will apply styles prefixed with dark:.

### Step 2: The Logic (The useEffect Hook)

I created a specific component called ThemeToggle.jsx. I needed a state variable to track the theme and a useEffect to handle the actual DOM updates and LocalStorage.

Here is the logic:

```bash
import React, { useState, useEffect } from 'react';

const ThemeToggle = () => {
  const [theme, setTheme] = useState(null);

  useEffect(() => {
    // 1. Check Local Storage first
    if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
      document.documentElement.classList.add('dark');
      setTheme('dark');
    } else {
      document.documentElement.classList.remove('dark');
      setTheme('light');
    }
  }, []);

  const toggleTheme = () => {
    if (theme === 'dark') {
      document.documentElement.classList.remove('dark');
      localStorage.theme = 'light'; // Save preference
      setTheme('light');
    } else {
      document.documentElement.classList.add('dark');
      localStorage.theme = 'dark'; // Save preference
      setTheme('dark');
    }
  };

  // Prevent rendering until theme is determined to avoid UI flicker
  if (!theme) return null; 

  return (
    <button 
      onClick={toggleTheme}
      className="p-2 rounded-full bg-gray-200 dark:bg-gray-800 transition-colors duration-200"
    >
      {theme === 'dark' ? '🌞' : '🌙'}
    </button>
  );
};

export default ThemeToggle;
```

### Step 3: Styling the UI with dark: classes

This is the fun part. With the logic handling the &lt;html&gt; class, I could just go through my components and decide how they look in the dark.

For example, my main project cards look like this:

```bash
<div className="bg-white text-gray-900 dark:bg-slate-800 dark:text-white shadow-lg p-6 rounded-xl">
  <h2 className="text-xl font-bold">Project Title</h2>
  <p className="text-gray-600 dark:text-gray-300">
    This description text automatically dims when dark mode is active.
  </p>
</div>
```

I love this approach because the styles live right next to each other. I don't have to maintain a separate dark-theme.css file.

### The "System Preference" Check

Notice the logic in the useEffect above:

```bash
('(prefers-color-scheme: dark)').matches
```

This ensures that if a user visits my site for the first time, and their MacBook is already in Dark Mode, my site respects that immediately without them having to click anything. It feels seamless.

### See It in Action

It’s one thing to read the code, but it’s another to see the transition animation in real-time.

Go to this [website](https://iap-six.vercel.app), look for the Moon/Sun icon in the Navbar, and give it a click. Watch how the colors invert smoothly (thanks to a global transition-colors class).

> ### Thanks for reading!
> 
> If you enjoyed this breakdown, you might like my personal portfolio where I showcase my latest builds using this exact stack.
> 
> 🚀 [**Check out the Live Demo on my Portfolio at uzairalam.me**](https://www.google.com/url?sa=E&q=https%3A%2F%2Fuzairalam.me)
> 
> 👋 *Connect with me on* [Twitter](https://x.com/robertdrowninjr) *or* [LinkedIn](https://linkedin.com/in/uzair1723) *for more updates.*
