cross-posted from: https://lemmy.dbzer0.com/post/62659556
Edit: I managed to get it working by using :has and nesting css classes!
body:has(#theme-toggle:checked) {
background-color: #eff1f5;
.content {
color: #4c4f69;
}
.header {
color: #8839ef
}
.nav {
background-color: #dce0e8;
color: #4c4f69;
}
}
I’m making a website for my school’s robotics team and I’m trying to create a dark theme toggle but it’s just not working. I’m trying to avoid javascript and I’ve seen this kind of thing done with only css and html before so I know it’s possible. any advice?
edit: currently my code looks something like this:
#theme-toggle:checked ~ body {
background-color: #eff1f5;
color: #fff;
}
#theme-toggle:checked ~ html {
background-color: #eff1f5;
}
#theme-toggle:checked ~ .content {
background-color: #eff1f5;
}
the button itself is a checkbox that has display set to none and the label set as an svg so when you click the icon, it gets checked.
<input style="display: none;" type="checkbox" id="theme-toggle">
<label for="theme-toggle" class="theme-button">
<img class="theme-button-svg" src="./icons/half-moon.svg">
</label>
I used a similar strategy when making the menu for the site so I know it should work
.menu {
position:absolute;
margin:0%;
right:20px;
top:20px;
}
.menu-button {
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 30px;
height: 22px;
cursor: pointer;
z-index: 2; /* above menu */
}
.menu-button span {
display: block;
height: 4px;
background-color: #cba6f7;
border-radius: 2px;
transition: all 0.3s ease;
}
.menu-items {
top: 30px;
right: -20px;
width: 200px;
background-color: #181825;
position: absolute;
display: none;
}
.menu-items li {
margin: 20px 0;
}
.menu-items a {
text-decoration: none;
color: #cba6f7;
font-size: 18px;
padding:5px;
}
.menu-items a:hover {
text-decoration: none;
background-color: #cba6f7;
color: #181825;
font-size: 18px;
}
.menu-selected {
text-decoration: underline;
text-decoration-color: #cdd6f4;
text-decoration-thickness: 3px;
}
.menu-selected:hover {
text-decoration-color: #181825;
}
#menu:checked ~ .menu-items {
display: inline;
}
#menu:checked + .menu-button span:nth-child(1) {
transform: rotate(45deg) translate(5px, 7.5px);
}
#menu:checked + .menu-button span:nth-child(2) {
opacity: 0;
}
#menu:checked + .menu-button span:nth-child(3) {
transform: rotate(-45deg) translate(5px, -7.5px);
}
<input style="display: none;" type="checkbox" id="menu">
<label for="menu" class="menu-button">
<span></span>
<span></span>
<span></span>
</label>


I don’t know about a non-javascript toggle but you can automatically apply dark theme styles with the “prefers-color-theme: dark” media query:
.theme-a { background: #ddccaa; color: #773311; } @media (prefers-color-scheme: dark) { .theme-a.adaptive { background: #775533; color: #ddccbb; outline: 5px dashed black; } }https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/prefers-color-scheme
I already have a dark theme set, I’m using catppuccin’s colors What I’m trying to have it do is when a button is pressed, it switches to the light version of it
currently my code looks something like this:
#theme-toggle:checked ~ body { background-color: #eff1f5; color: #fff; } #theme-toggle:checked ~ html { background-color: #eff1f5; } #theme-toggle:checked ~ .content { background-color: #eff1f5; }the button itself is a checkbox that has display set to none and the label set as an svg so when you click the icon, it gets checked.
<input style="display: none;" type="checkbox" id="theme-toggle"> <label for="theme-toggle" class="theme-button"> <img class="theme-button-svg" src="./icons/half-moon.svg"> </label>I used a similar strategy when making the menu for the site so I know it should work
The problem with
#theme-toggle:checked ~bodyis that the selector is wrong.~requires that the second part comes after the first part in the HTML. But your toggle is inside thehtmland thebody. [1]Use the new-ish
:hasselector [2]:html:has(#theme-toggle:checked) { background-color: #eff1f5; }[1] https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/Subsequent-sibling_combinator
[2] https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:has
Thanks, it’s working perfectly!
I’m glad that after 5-ish years of doing this shit professionally I finally know enough to help others! :D
ok, I have a new problem, it doesn’t work when I try to use the class for example
.content:has(#theme-toggle:checked) { color: #4c4f69; }won’t work :[
Did you read the article I linked which explains what the
:hasselector does?