DEV Community

Paweł Czarnecki
Paweł Czarnecki

Posted on • Updated on

Multiple themes with JS and JSON

First let's create themes container in html

<div class="themes">
    <div class="theme" onclick="changeTheme('light')"></div>
    <div class="theme" onclick="changeTheme('dark')"></div>
    <div class="theme" onclick="changeTheme('blue')"></div>
</div>
Enter fullscreen mode Exit fullscreen mode

and content container to see changes after choosing theme

<div class="container">
  <h2>Container</h2>
  Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore magnam atque, minima doloribus reprehenderit libero necessitatibus dicta vel obcaecati? Provident totam adipisci veniam aperiam 
</div>
Enter fullscreen mode Exit fullscreen mode

Now we are going to add some basic styling

* {
    margin: 0;
    padding: 0;
    font-family: 'Poppins', sans-serif;
    box-sizing: border-box;
}
body {

}
.themes {
    display: flex;
    justify-content: space-around;
    align-items: center;
    border-radius: 8px;
    padding: 20px;
    width: 200px;
    margin-left: 1rem;
    margin-top: 20px;
    .theme {
        width: 30px;
        border-radius: 8px;
        height: 30px;
        cursor: pointer;
        &:nth-child(1) {
            background-color: #ddd;
        }
        &:nth-child(2) {
            background-color: #333;
        }
        &:nth-child(3) {
            background-color: rgb(5, 2, 57);
        }
    }
}
.container {
    width: min(calc(100% - 2rem), 1200px);
    margin-top: 80px;
    margin-inline: auto;
    padding: 20px;
}
Enter fullscreen mode Exit fullscreen mode

And our default theme

:root {
    --bg-color: #eee;
    --secondary: #ccc;
    --text: #333;
}
body {
    background-color: var(--bg-color);
    color: var(--text);
}
.themes {
       background-color: var(--secondary);
}
.container {
    background-color: var(--secondary);
}
Enter fullscreen mode Exit fullscreen mode

We have our project which looks something like this

Image description

Ok, so now we can create themes in json

[
    {
        "id": "light",
        "colors": {
            "bgColor": "#eee",
            "secondary": "#ccc",
            "text": "#333"
        }
    },
    {
        "id": "dark",
        "colors": {
            "bgColor": "#333",
            "secondary": "#222",
            "text": "#ddd"
        }
    },
    {
        "id": "blue",
        "colors": {
            "bgColor": "rgb(5, 2, 57)",
            "secondary": "rgb(47, 23, 102)",
            "text": "rgb(235, 235, 235)"
        }
    }
]

Enter fullscreen mode Exit fullscreen mode

We have almost everything except javascript. First, we need the function we are calling in html

const changeTheme = (theme) => {

}
Enter fullscreen mode Exit fullscreen mode

Our function is created, now we need to load themes from json file

const changeTheme = (theme) => {
    fetch('./themes.json')
        .then((response) => response.json())
        .then((data) => {

    })
}
Enter fullscreen mode Exit fullscreen mode

We have successfully loaded our themes, the last thing to do is to use them. Let's filter through all of our themes and choose one matching the users's choice

data.filter((data) => {
    const { id, colors: { bgColor, secondary, text }} = data
    if (id === theme) {

    }
})
Enter fullscreen mode Exit fullscreen mode

Finally, we will set the colors of the CSS properties to the colors of the selected theme

document.documentElement.style.setProperty('--bg-color', bgColor)
document.documentElement.style.setProperty('--secondary', secondary)
document.documentElement.style.setProperty('--text', text)
Enter fullscreen mode Exit fullscreen mode

As a bonus we can use localStorage to save our themes

localStorage.setItem('bgColor', bgColor)
localStorage.setItem('secondary', secondary)
localStorage.setItem('text', text)
Enter fullscreen mode Exit fullscreen mode

and load them from localStorage

document.documentElement.style.setProperty('--bg-color', localStorage.getItem('bgColor'))
document.documentElement.style.setProperty('--secondary', localStorage.getItem('secondary'))
document.documentElement.style.setProperty('--text', localStorage.getItem('text'))
Enter fullscreen mode Exit fullscreen mode

Our simple page now looks like this

Image description

Image description

Image description

For all project files visit my Github Respository

If you want to see more of my work visit my Github or Codepen profile

Top comments (1)

Collapse
 
tilakjain123 profile image
Tilak Jain

Nice Post