16
Problems with dark-theme toggle
(lemmy.dbzer0.com)
submitted
4 days ago* (last edited 3 days ago)
by
WrenHavoc@lemmy.dbzer0.com
to
c/webdev@programming.dev
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?
repo: https://github.com/WrenHavoc/JudgeMent-Call-Website
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 think this will work. Read up on what the "subsequent sibling" selector really does and double check that it's what you really want here.
Also check out the color-scheme property and the articles listed under the See also heading.
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme#see_also
Maybe that can give you some ideas where you need to brush up on modern dark mode styling. ๐
I got a piece of code from c/programming that works Using body:has(#theme-toggle:checked)
I prefer doing it that way because I use a browser with anti-fingerprinting which hides the preferred theme so prefers-color-scheme doesn't work as well
Check this simple example out:
You don't need any fancy selectors with this method. Will this not work in your browser due to the anti-fingerprinting feature?
I will say, avoiding JavaScript completely will make the value reset after each reload, so might not be very useful perhaps, depending on your needs. You could store the value in
localStorage, perhaps.I think this could work with css variables. This way you can define it in root and then some sibling selector could switch the value. That way you can use the variable anywhere in code.
CSS variables yes, that's fine. But using this selector in this way, especially with body and html as the "subsequent sibling", won't work (well). The body and html elements can't be siblings of a checked element.
Yep. Op needs to discover :has