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" />
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"
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>
</>
);
}
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>
)
}
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;
}
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)",
},
},
},
},
// ...
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;
}
}
Top comments (0)