I’m been trying to integrate a theme button into my website but unfortunately, it doesn’t work properly. When the page is refreshed the button toggles to the initial phase but the page remains with the theme that was set previously
I want the button to remain locked after setting a statement (light theme or dark one)
Function:
// function to set a given theme/color-scheme
function setTheme(themeName) {
localStorage.setItem('theme', themeName);
document.documentElement.className = themeName;
}
// function to toggle between light and dark theme
function toggleTheme() {
if (localStorage.getItem('theme') === 'theme-dark'){
setTheme('theme-light');
} else {
setTheme('theme-dark');
}
}
// Immediately invoked function to set the theme on initial load
(function () {
if (localStorage.getItem('theme') === 'theme-dark') {
setTheme('theme-dark');
} else {
setTheme('theme-light');
}
})();
CSS:
.theme-light {
--color-body: #2610ff;
--background-body: #fff;
--heading-color: #226229;
--font-color: #000000;
--color-mainNav: rgba(255, 255, 255, 0.9);
--text-mainNav: #333;
--background-header: #a09b9b42;
--background-featured: #4b3bf4;
}
.theme-dark {
--color-body: #999CFF;
--background-body: #000000;
--heading-color: #3EB14E;
--font-color: #ffffff;
--color-mainNav: rgba(0, 0, 0, 0.8);
--text-mainNav: #dbd5d5;
--background-header: #45444880;
--background-featured: rgb(38, 0, 255);
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: relative;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: "";
height: 40px;
width: 40px;
left: 0px;
bottom: 4px;
top: 0;
margin: auto 0;
-webkit-transition: 0.4s;
transition: 0.4s;
box-shadow: 0 0px 15px #2020203d;
background: white url('https://i.ibb.co/7JfqXxB/sunny.png');
background-repeat: no-repeat;
background-position: center;
}
input:checked + .slider {
background-color: #2196f3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196f3;
}
input:checked + .slider:before {
-webkit-transform: translateX(24px);
-ms-transform: translateX(24px);
transform: translateX(24px);
background: white url('https://i.ibb.co/FxzBYR9/night.png');
background-repeat: no-repeat;
background-position: center;
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
HTML:
<link rel="stylesheet" href="./style.css">
<body class="body">
<label id="switch" class="switch">
<input type="checkbox" onchange="toggleTheme()" id="slider">
<span class="slider round"></span>
</label>
</body>
I’ve created a codepen so maybe someone will help me out with my problem
2
Answers
I believe your problem is that you have forgotten to set initial state for the button when the page loads :
Additionally, it would we much better to come up with a solution to set state before rendering happens, like putting the function in separate script tag in the
<head>
.On initial load, there should be logic to change the state of the
#slider
checkbox element.