Theme Switcher
Build a toggle that switches the color scheme of the page between light and dark modes.
Solution
Headline
Section
This solution toggles CSS root values for font and background colours.
If light we use:
--fontColor: black; --bgColor: white;
If dark we use:
--fontColor: white; --bgColor: black;
Better solutions would also take account of the users preferences. You can see from this article how you need to access the system settings with media queries.
Explanation
isDark useState
The user preference for light or dark mode is stored in the state variable, isDark.
toggleDarkMode function
The toggleDarkMode function very simply returns the opposite of the current state. This is attached to the Toggle Theme button.
Adding the style to elements
A conditional style has been added to the container element with a ternary operator with either lightMode and darkMode being assigned.
The trick to changing the styles in CSS
The use of CSS Variables controls the output colours.
Both lightMode and darkMode have their own values for the variables --fontColor and --bgColor.
Look to the other CSS classes to see how those variables have been used to assign key colours. This means they can alter based off of which of the two classes lightMode or darkMode is used.
Code
import { useState } from "react";
import styles from "./Solution.module.css";
const Solution = () => {
const [isDark, setIsDark] = useState(false);
const toggleDarkMode = () => setIsDark((prevMode) => !prevMode);
return (
<div
className={`${styles.container} ${
isDark ? styles.darkMode : styles.lightMode
}`}
>
<button
onClick={toggleDarkMode}
aria-label="Dark mode toggle"
className={styles.buttonTheme}
type="button"
>
Toggle Theme
</button>
<h1>Headline</h1>
<section className={styles.section}>
<h2>Section</h2>
<p>
This solution toggles CSS root values for font and background colours.
</p>
<p>If light we use:</p>
<p>--fontColor: black; --bgColor: white;</p>
<p>If dark we use:</p>
<p>--fontColor: white; --bgColor: black;</p>
<p>
Better solutions would also take account of the users preferences. You
can see from this{" "}
<a href="https://blog.logrocket.com/dark-mode-react-in-depth-guide/#using-system-settings">
article
</a>{" "}
how you need to access the system settings with media queries.
</p>
</section>
</div>
);
};
export default Solution;
Styling
.lightMode {
--fontColor: black;
--bgColor: white;
}
.darkMode {
--fontColor: white;
--bgColor: black;
}
.buttonTheme {
color: var(--fontColor);
padding: 10px;
margin: 10px 0 20px;
background-color: var(--bgColor);
cursor: pointer;
border: 2px solid;
border-color: var(--fontColor);
scale: 1;
transition: scale 0.3s;
}
.buttonTheme:hover {
scale: 1.1;
}
.buttonTheme:active {
scale: 0.9;
}
.container {
padding: 10px;
transition: 0.3s;
color: var(--fontColor);
background-color: var(--bgColor);
}
.section {
max-width: 400px;
margin: 20px 0;
padding: 20px;
border: 1px solid;
border-color: var(--fontColor);
}
.section p {
margin: 0.5rem 0;
}
.section a,
.section a:visited,
.section a:active {
color: inherit;
text-decoration: underline;
}