The idea is to use the variables with CSS for the dark and light theme.
🟡 Configuring variables for light theme.
We create a folder called src/styles and create the file var.css.
This file will be in charge of setting the CSS variables.
1- To set the variables inside CSS we use pseudo-class root as follows
:root{}
Inside we place the variables we are going to use. To define variables we use this syntax
--background:#f2f2f2;
We have to place a double hyphen before the custom name of our property, then, we place a colon and add the value of that property.
Here are the other variables:
Note that for the dark theme variables, we no longer use the pseudo-class root, but we reference a custom attribute that we are defining as theme.
This custom attribute, has to be placed in an HTML tag for the dark mode to work (Do not place the attribute manually, this will be done dynamically, using react).
But not in just any tag, it must be placed in the highest hierarchy tag, such as the body.
This is an example of how it should look
<bodydata-theme='dark'><!-- content --><body>
If we place the data-theme attribute in the other tag with less hierarchy, only the content of that tag will use the dark mode.
For this reason, it should be placed in the tag with the highest hierarchy.
<body><divdata-theme='dark'><!-- Dark theme --></div><div><!-- Light theme --></div><body>
🟡 Using the variables in our style.
Now, notice that we have created a var.css file inside src/styles. But where do we import them?
Well, in my case I found it best to import them into the src/index.css file.
To import .css files into another .css file we use @import url() and add the path where the file to import is located.
This is a good practice to separate the CSS files as it helps to understand better the code of the styles.
By the way, you must place the import at the top of your file.
Once the variables have been placed in the other styles (in the cards, switch and title), we will proceed with adding the logic for switching between themes.
💡 Adding the logic to switch between themes.
First, we have to control the state of the switch to be able to get when it is 'on' / 'off' and depending on those values use one theme or another.
🟡 Controlling the state of the switch.
1- First we add a state. This state will be of type Theme, and will only accept the string 'dark' or 'light'.
2- We create the function to control the switch event.
Which, receives as parameter the event that emits by default the input.
The function calls the setter setTheme and inside it makes an evaluation:
If the checked property of the input is set to true, it sets the 'dark' theme.
If the checked property of the input is false, it sets the 'light' theme.
Now, the function handleChange is going to be executed when the input of type checkbox has a change and for that reason we pass it to method onChange.
And the checked property of the same input, we will pass an evaluation, since the checked property only accepts boolean values. The evaluation will be:
If the value of the state theme is 'dark', the value of checked will be true.
If the value of the state theme is 'light', the value of checked will be false.
3- And now, remember that we were going to place the custom attribute data-theme, well now it's time to do it.
For this we use an effect, which must be executed every time the value of the theme state changes. That's why we place it in its dependency array of the useEffect.
Then, inside the useEffect we execute the following:
document.body.setAttribute('data-theme',theme);
Basically, we are accessing the body tag (because it is the highest point that encloses all our application), and we set a new attribute with the function setAttribute.
setAttribute, receives in this case two parameters:
the name of the new attribute.
the value for that new attribute.
So, we set the data-theme attribute with the value of the theme state.
And now it is definitely cleaner and easier to read our component! 🥳
💡 Conclusion.
The whole process I just showed, is one of the ways you can do the functionality to create dark mode and switch between themes, without using some external library. 🌙
I hope I helped you understand how to make this functionality and that you manage to apply it in your future projects, thank you very much for getting this far! 🤗❤️
I invite you to comment if you know any other different or better way of how to do this functionality. 🙌