DEV Community

mhcrocky for sedecx

Posted on

4 1

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

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay