DEV Community

Cover image for Making a Vuejs dark theme toggle
Brett Anda 🔥🧠 for Developer Bacon 🥓🥓

Posted on • Originally published at developerbacon.ca on

Making a Vuejs dark theme toggle

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) {}
})();

Enter fullscreen mode Exit fullscreen mode

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>

Enter fullscreen mode Exit fullscreen mode

If you would like to see this code in action check out the navigation on Developer Bacon.

Latest comments (2)

Collapse
 
mburszley profile image
Maximilian Burszley • Edited

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.

Collapse
 
brettanda profile image
Brett Anda 🔥🧠

I totally forgot. Thanks!