DEV Community

mhcrocky for Flarehub

Posted on

Dark mode in Next.js using Tailwind CSS

Now that dark mode is a first-class feature of many operating systems, it’s becoming more and more common to design a dark version of your website to go along with the default design.

Tailwind includes a dark variant that lets you style your site differently when dark mode is enabled:

<div class="bg-white dark:bg-slate-900" />
Enter fullscreen mode Exit fullscreen mode

The only problem now is to implement a theme manager. But there is no need to reinvent the wheel here, there is an excellent package called next-themes.

To setup dark mode you need enable dark mode in tailwind.config.js.

darkMode: "class"

Enter fullscreen mode Exit fullscreen mode

Then enable class mode in next-themes _app.tsx

import { ThemeProvider } from "next-themes";
// ...
function MyApp({ Component, pageProps }: AppProps) {
  return (
    <>
      <ThemeProvider
        attribute="class"
        defaultTheme="system"
        storageKey="some-key-for-your-application"
      >
         <Component {...pageProps} />
      </ThemeProvider>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Then you can create a reusable theme changer component

import { useTheme } from 'next-themes'

const ThemeChanger = () => {
  const [mounted, setMounted] = useState(false)
  const { theme, setTheme } = useTheme()

  // When mounted on client, now we can show the UI
  useEffect(() => setMounted(true), [])

  if (!mounted) return null

  return (
    <div>
      The current theme is: {theme}
      <button onClick={() => setTheme('light')}>Light Mode</button>
      <button onClick={() => setTheme('dark')}>Dark Mode</button>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

And now any classes with dark variant will active when you toggle themes.

*Extending with variables
*

You can extend this feature with CSS variables. This will allow you to add single class in classNames but allow for both themes and it much better for customizing your website to your brand liking.

Setup CSS variables in globals.css

.light {
  --color-text-base: #3c4043;
  --color-text-muted: #5f6368;
  --color-background-base: #ffffff;
}
.dark {
  --color-text-base: #e8eaed;
  --color-text-muted: #9aa0a6;
  --color-background-base: #202124;
}
Enter fullscreen mode Exit fullscreen mode

Setup up classes in tailwind.config.js

// ...
theme: {
    extend: {
      textColor: {
        skin: {
          base: "var(--color-text-base)",
          muted: "var(--color-text-muted)",
        },
      },
      backgroundColor: {
        skin: {
          base: "var(--color-background-base)",
        },
      },
    },
  },
// ...

Enter fullscreen mode Exit fullscreen mode

Example code: globals.scss.

@layer base {
  html {
    @apply h-full;
  }
  body {
    @apply text-skin-base bg-skin-base h-full;
  }

  div#__next {
    @apply h-full;
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)