I have been trying and failing to add a dark mode to my website for the past few days. I looked at a few tutorials and asked a few people, and it seems like my problem is having !important in my CSS. I’ve been reading up on Cascade Layers, but I’m not at all sure what selector to use. Is that the best fix?
I may have tried to do something beyond my existing scope of CSS knowledge…if you think I need to learn more CSS first, please let me know of a good place to learn! W3Schools is not working for me.
My preferred approach is light-dark() CSS, which I see you’ve already tried. Can you show us the exact code you wrote with it? I can try and troubleshoot with you.
and change the colors inside. You’re also going to need a meta element in the page head:
<meta name="color-scheme" content="light dark">
You can also do it in your CSS like this:
:root { Color-scheme: light dark; }
But it doesn’t always work, not sure why. So it’s best to use the meta element if you can.
Either way, using !important will make it impossible to override properties later. That’s kind of the point, and why it’s usually considered a mistake. Hope this helps!
Yeah, I at least learnt the issues with !important through this – unfortunately, it was a part of the mobile responsive tutorial someone had put out I’ve just removed them at the moment, but I’m scared of if/how that will affect things.
The good news is that it made my background actually dark. The bad news is that it changed my font color in the navigation for some reason?
I also forgot to ask this specifically earlier, but is there a way to do color-scheme where repeating background images are still happening? Or does dark mode necessitate CSS only backgrounds?
Yes, my personal site uses repeating background images alongside color-scheme and light-dark().
It looks like you’ve changed things in the code since I last looked at it, so at the moment I’m not sure where to find the definitions for your variables/custom properties.
Regardless, it seems like your code has a lot of things going on, and maybe not all the applicable elements have the right variables attached. For instance, I noticed your body CSS looks like this:
The color var(–text) is a different name than what many of the other rules have, var(–text-color). If you meant for these to be different, that’s fine. If not, then this goes to show why it’s safer to just stick text color in the body CSS so that you don’t end up creating unintended exceptions.
Using frames may be messing with things here as well. I don’t have experience with those, but it looks like they may be adding some inline CSS, and with your code scattered across multiple places in that way it can be more difficult to narrow things down for troubleshooting. For now I’m inclined to suggest that you start fresh with a new page where you can test, and then later you can add all the other layers back on top.
Are you dead set on having a selectable dark mode? If not, I find the easiest way to do it (since it doesn’t involve any JavaScript whatsoever) is to just use media rules and respect the user’s system preferences.
This is the only CSS I use to control light vs dark mode on my site:
If the visitor has dark mode set in their browser, then the dark mode hex values are automatically applied without them having to click on anything. Otherwise, it defaults to the light mode values. No need for !important. The only thing I have to remember is to use var(--insert-root-color-name-here) when I’m specifying what colour I want the various elements of my style sheet to be. For instance:
I figure if someone is dead set on using dark mode on a website, they likely already have dark mode set at the system level. This set up is also very convenient for people like me who set their computers to automatically switch over to dark mode at a certain time of the day.
True, but as per that guide, you do need JavaScript to save the visitor’s theme preferences for future visits, or when navigating to other pages. A JS-free theme switcher only really works for a single page website; it would be too annoying to have to select the theme you want every time you load a different page. At least with media rules, theme application is automatic and persistent across all pages without needing to save anything in localStorage.
The same is true if you combine it with light-dark(). I use that method for my Deviation template – light-dark to pick up on browser preferences, a radio input to allow switching, and then optional javascript to save your preferences if you switch away from your default browser setting.
Yup. Any selectable dark mode or light mode (no matter what technique is used) requires JavaScript to save preferences across multiple pages and return visits. I don’t like using JavaScript on my website, so I just let the visitor’s system preferences for dark vs light mode dictate which colours get loaded in lieu of making the two themes selectable on the site itself. That way, people who don’t have JS enabled in their browsers still get to use dark mode on the site (via their browser or system preferences) without the annoyance of having to toggle it back on every time they click on a different page.
Thank you for catching the var(--text-color) thing! That immediately fixed at least part of my problems.
I think the redundant code was the mobile theme, which I had made a separate CSS file for, but apparently forgotten to delete the original of. Hopefully it’s a bit less confusing now?
The light/dark mode is technically working, though only on the middle bit, and requires a page refresh. I’m not sure if that is due to the frames.
Update: I now have dark mode working on all frames, but the button only seems to affect the navigation frame. Graaah. Is it time to abandon frames after all?
I may hold off on background patterns for now, I thought I’d hate how it looked. Turns out it looks just fine!
Could be. Personally I find too much stuff on one page to be distracting, and I’m not sure how well they play with screen readers. Congrats on getting the buttons themselves working though!