Making a dark theme with CSS variables and @media
If you haven't read my previous article on making a dark theme with CSS variables. Check it out before reading this because this is a continuation of that article.
The first called script
This script should be called as soon as possible so that the proper CSS can be applied to the document. If you are using Gridsome, you can add this script to your index.html
file. This code checks for what the color them of the device is then set a local storage variable and a data attribute to the theme name. For example, if the devices color scheme was set for 'dark mode' the local storage variable and data attribute would be set to dark
.
Setting a data attribute makes it possible to change the CSS based on the color scheme.
(function() {
try {
// Checks for the color scheme of the device.
// In this case it checks for anything that is not light theme.
var media = window.matchMedia("not all and (prefers-color-scheme: light)"),
body = document.body;
if (localStorage.getItem("theme") == "dark") {
body.setAttribute("data-theme", "dark");
} else if (localStorage.getItem("theme") == "light") {
body.setAttribute("data-theme", "light");
} else if (media.matches) {
body.setAttribute("data-theme", "dark");
localStorage.setItem("theme", "dark");
}
media.addListener(function() {
if (media.matches) {
body.setAttribute("data-theme", "dark");
localStorage.setItem("theme", "dark");
} else {
body.setAttribute("data-theme", "light");
localStorage.setItem("theme", "light");
}
});
} catch (err) {}
})();
Theme Toggle Component
In the navigation, I have made a button component to toggle the theme. This is the HTML for that component.
<template>
<button
:title="theme == 'dark' ? 'Dark Theme' : 'Light Theme'"
@click="toggleTheme()"
class="theme"
>
<Moon :is="theme == 'dark' ? 'Moon' : 'Sun'" height="20px" />
</button>
</template>
<script>
import Moon from "~/assets/images/moon-regular.svg";
import Sun from "~/assets/images/sun-regular.svg";
export default {
components: {
Moon,
Sun
},
data() {
return {
theme: localStorage.getItem("theme")
};
},
methods: {
toggleTheme() {
if (this.theme == "dark") {
this.theme = "light";
document.body.setAttribute("data-theme", "light");
localStorage.setItem("theme", "light");
} else {
this.theme = "dark";
document.body.setAttribute("data-theme", "dark");
localStorage.setItem("theme", "dark");
}
}
}
};
</script>
If you would like to see this code in action check out the navigation on Developer Bacon.
Top comments (2)
It would probably help if you use the language feature for your code gates. Non-syntax-highlighted code is just a drag to read nowadays.
I totally forgot. Thanks!