Linda Ojo

Darkmode using CSS variables - Vue JS

Published: 2020-11-02
preview-image

In this article, we are going to cover how to add dark mode to a Vue JS application using CSS variables

Variables for the default theme should be placed under :root, while the variables for dark mode can be placed under the data-theme attribute. Make sure data-theme is set to "darkMode" as shown below

main.css
:root {
    /* Variables for default theme (light-mode) */
    --background-color: white;
    --text-color: black;  
}

[data-theme="darkMode"] {
    /* Variables for dark mode */
    --background-color: black;
    --text-color: white;   
}

We can use the var() function to insert the value of the variables we just created in our CSS. Take a look at the example below.

main.css
.example {
    background-color: var(--background-color);
    color: var(--text-color);
}

These variables help us switch between styles with ease.

💡 You would want users to be able to switch themes anywhere within your site so I recommend adding the theme toggle element to your header.

To toggle between the two themes, let's add a function called Toggle theme which will be triggered by a button.

header.vue
 <button  @click="toggleTheme" aria-label="Toggle themes">
    <span>Toggle Theme</span>  
 </button>


data() {
    return {
        theme: '' //When this property is empty, the theme is set to the default theme i.e. light mode.
    };
},

toggleTheme() {
            this.theme = this.theme == 'darkMode' ? '' : 'darkMode'; //toggles theme value
            document.documentElement.setAttribute('data-theme', this.theme); // sets the data-theme attribute
            localStorage.setItem('theme', this.theme); // stores theme value on local storage
}

Now we can toggle dark mode by clicking on the toggle theme button.

We also need to set the theme when the page loads. We do this in Vue JS within the Mounted Life-Cycle hook.

header.vue
    mounted() {
        let localTheme = localStorage.getItem('theme'); //gets stored theme value if any
        document.documentElement.setAttribute('data-theme', localTheme); // updates the data-theme attribute
    },

We can now switch the content of the button element based on the active theme using Vue's Conditional Rendering as shown below.

header.vue
 <button @click="toggleTheme" aria-label="Toggle themes">
    <span v-if="this.theme == 'darkMode'"> Light</span>
    <span v-else> Dark</span>     
</button>

Here is a holistic view of the previous code snippets working together.

header.vue
 <button  @click="toggleTheme" aria-label="Toggle themes">
    <span v-if="this.theme == 'darkMode'"> Light</span>
    <span v-else> Dark</span>     
</button>

<script>
export default {
    data() {
        return {
            theme: '' //When this property is empty, the theme is set to the default theme i.e. light mode.
        };
    },

    mounted() {
        let localTheme = localStorage.getItem('theme'); //gets stored theme value if any
        document.documentElement.setAttribute('data-theme', localTheme); // updates the data-theme attribute
    },

    toggleTheme() {
                this.theme = this.theme == 'darkMode' ? '' : 'darkMode'; //toggles theme value
                document.documentElement.setAttribute('data-theme', this.theme); // updates the data-theme attribute
                localStorage.setItem('theme', this.theme); // stores theme value in local storage
    }
}
<script>

Now we can toggle between light and dark mode and the user's preferred mode is stored locally, pretty neat!

Subscribe to Newsletter

Be the first to know about quality articles and poems written by Linda Ojo.