I am making a theme toggle switch but when i click on the toggle button, it's not reaching the right end making some part of the icon visible. The left side is okay so it's only the right side.
I have tried changing something like the right size or switching the toggle to start from the right to left which works fine if i do that but it feels like running away from the problem.
See full toggle in codepen
https://codepen.io/salarymantech/pen/LEYwadY
This is my code below
.switch-toggle {
display: none;
appearance: none;
-webkit-appearance: none;
visibility: hidden;
opacity: 0;
width: 0;
height: 0;
}
.theme-switch {
display: block;
position: relative;
width: 70px;
height: 36px;
cursor: pointer;
transition: all 0.7s ease-out;
}
.switch-buttons {
position: relative;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
background-color: var(--dark);
transition: all 0.5s ease-out;
border-radius: 10px;
border: 5px solid var(--light);
}
.switch-buttons::after {
content: "";
position: absolute;
top: 5px;
left: 6px;
width: 26px;
height: 26px;
background-color: var(--light);
border-radius: 10%;
transition: all 0.5s ease-out;
}
.switch-toggle:checked + .switch-buttons {
background-color: var(--light);
border: 5px solid var(--dark);
}
.switch-toggle:checked + .switch-buttons::after {
right: 6px;
transform: translateX(100%);
background-color: var(--dark);
position: absolute;
content: "";
}
You'll need to add 6px
to the translateX
to account for the distance between the sun and the moon:
transform: translateX(calc(100% + 6px));
[data-theme="light"] {
--dark: #ffffff;
--light: #eedf79;
--background-color: #1a1a1a;
--text-color: #4d4d4d;
--header-color: #1c274c;
--button-background: #1c274c;
--button-color: #eedf79;
--button-hover-background: #eedf79;
--button-hover-color: #1c274c;
--link-color: #1c274c;
--link-hover-color: #eedf79;
--border-color: #1c274c;
}
[data-theme="dark"] {
--dark: #882241;
--light: #eedf79;
--background-color: #1a1a1a;
--text-color: #fefefe;
--header-color: #eedf79;
--button-background: #882241;
--button-color: #eedf79;
--button-hover-background: #eedf79;
--button-hover-color: #882241;
--link-color: #882241;
--link-hover-color: #eedf79;
--border-color: #882241;
}
html,
body {
margin: 0;
padding: 0;
font-family: "Jost", serif;
font-weight: 400;
font-size: 16px;
background-color: var(--background-color);
color: var(--text-color);
line-height: 1.5;
border-bottom: 50px #eedf79;
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 2s;
}
@keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.theme {
position: absolute;
top: 50%;
left: 50%;
}
.switch-toggle {
display: none;
appearance: none;
-webkit-appearance: none;
visibility: hidden;
opacity: 0;
width: 0;
height: 0;
}
.theme-switch {
display: block;
position: relative;
width: 70px;
height: 36px;
cursor: pointer;
transition: all 0.7s ease-out;
}
.switch-buttons {
position: relative;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
background-color: var(--dark);
transition: all 0.5s ease-out;
border-radius: 10px;
border: 5px solid var(--light);
}
.switch-buttons::after {
content: "";
position: absolute;
top: 5px;
left: 6px;
width: 26px;
height: 26px;
background-color: var(--light);
border-radius: 10%;
transition: all 0.5s ease-out;
}
.switch-toggle:checked+.switch-buttons {
background-color: var(--light);
border: 5px solid var(--dark);
}
.switch-toggle:checked+.switch-buttons::after {
transform: translateX(calc(100% + 6px));
background-color: var(--dark);
position: absolute;
content: "";
}
.sun::after,
.moon::after {
content: "";
position: absolute;
top: 6px;
width: 26px;
height: 26px;
}
.sun::after {
background-image: url("https://raw.githubusercontent.com/salaryman-technologies/quickpick/refs/heads/main/sun.svg");
left: 6px;
}
.moon::after {
background-image: url("https://raw.githubusercontent.com/salaryman-technologies/quickpick/refs/heads/main/moon.svg");
right: 6px;
}
<html data-theme="light">
<head></head>
<body>
<div class="theme">
<label for="theme-switch" class="theme-switch">
<input type="checkbox" class="switch-toggle" id="theme-switch">
<div class="switch-buttons">
<div class="sun"></div>
<div class="moon"></div>
</div>
</label>
</div>
</body>
</html>
You can also minimize the amount of markup and styling by using multiple background images on the label, and the :has
pseudo-class:
*,
*::before,
*::after {
box-sizing: border-box;
}
.theme-switch {
display: block;
position: relative;
width: 80px;
height: 45px;
border-radius: 10px;
border: 5px solid var(--light);
background-image:
url("https://raw.githubusercontent.com/salaryman-technologies/quickpick/refs/heads/main/sun.svg"),
url("https://raw.githubusercontent.com/salaryman-technologies/quickpick/refs/heads/main/moon.svg");
background-position: 6px 6px, right 6px top 6px;
background-repeat: no-repeat;
background-color: var(--dark);
cursor: pointer;
transition: all 0.5s ease-out;
&::after {
position: absolute;
top: 5px;
left: 6px;
width: 26px;
height: 26px;
background-color: var(--light);
border-radius: 10%;
transition: all 0.5s ease-out;
content: "";
}
&:has(:checked) {
background-color: var(--light);
border: 5px solid var(--dark);
&::after {
transform: translateX(calc(100% + 6px));
background-color: var(--dark);
}
}
}
[data-theme="light"] {
--dark: #ffffff;
--light: #eedf79;
--background-color: #1a1a1a;
--text-color: #4d4d4d;
--header-color: #1c274c;
--button-background: #1c274c;
--button-color: #eedf79;
--button-hover-background: #eedf79;
--button-hover-color: #1c274c;
--link-color: #1c274c;
--link-hover-color: #eedf79;
--border-color: #1c274c;
}
[data-theme="dark"] {
--dark: #882241;
--light: #eedf79;
--background-color: #1a1a1a;
--text-color: #fefefe;
--header-color: #eedf79;
--button-background: #882241;
--button-color: #eedf79;
--button-hover-background: #eedf79;
--button-hover-color: #882241;
--link-color: #882241;
--link-hover-color: #eedf79;
--border-color: #882241;
}
html,
body {
margin: 0;
padding: 0;
font-family: "Jost", serif;
font-weight: 400;
font-size: 16px;
background-color: var(--background-color);
color: var(--text-color);
line-height: 1.5;
border-bottom: 50px #eedf79;
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 2s;
}
@keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.theme {
position: absolute;
top: 50%;
left: 50%;
}
<html data-theme="light">
<div class="theme">
<label for="theme-switch" class="theme-switch">
<input type="checkbox" class="switch-toggle" id="theme-switch" hidden>
</label>
</div>