Change to dark mode with a button

I’m trying to find ways to change the color of the theme from the homepage.

I wish I could “activate” the CSS @media (prefers-color-scheme: dark) with a button.

So get this result, not only by changing the theme of the operating system, but also with a button.

it’s possible?

1 Like

Although I don’t recall any by name, I’ve seen a handful of themes that allow for this.

As well, and although I’m not able to copy and paste the code right now since I’m away from my laptop at the moment, but if you’re competent with CSS and JS you can grab the requisite code off of my blog which has its own way of allowing for this. If you’re interested, let me know and I can copy/paste over the requisite code tomorrow.

Ok thanks, if I have enough time today I’ll try!

If you still want the code, here it is, although don’t ask me about it since I don’t know JS. Furthermore, my dark mode functionality uses a toggle, which may very well be a part of the JS (just the first three lines?). And last of all, my dark mode functionality no longer detects the system dark/light setting as I preferred it defaulting to light mode. That being said, if you switch over to dark mode it’ll stay that way.

Array.from(document.getElementsByClassName('darkmode-toggle')).forEach(function addDarkmodeListeners(element) {
    element.onchange = darkmodeToggled;
});

function darkmodeToggled() {
    var input = this.querySelector('input');
    window.darkThrottled ? (input.checked = !input.checked) : darkmodeChanged(input.checked);
}

function unthrottleDarkMode() {
    window.darkThrottled = false;
}

function darkmodeChanged(state) {
    window.darkThrottled = true;
    localStorage.setItem('darkmode-enabled', state);
    Array.from(document.getElementsByClassName('dm-input')).forEach(function (element) {
        element.checked = state;
    });
    document.body.classList[state ? 'add' : 'remove']('dark');
    setTimeout(unthrottleDarkMode, 250);
}

if (localStorage.getItem('darkmode-enabled') === "true") {
    darkmodeChanged(true);
}

Following that, all classes that you want to switch over when you activate the toggle (or button?) will have to be preceded by body.dark. So for example, if for light mode you have

p {
    color: #000;
}

then for dark mode you’d have

body.dark p {
    color: #fff;
}

I could be mistaken, but I think the code was adapted from here:

Otherwise, I was able to find one blog in my bookmarks that uses a button for its dark mode functionality (it’s in the hamburger menu):

1 Like

hi, sorry if I answer only now but I didn’t have the time.
I was able to use the color change with the toggle from the front-end but without respecting the default settings of the css.

Creating custom css classes and using javascript as you did is good.
But i would like to run both the toggle button and the automatic system detection mode.

I’m looking for a solution to enable @media (prefers-color-scheme: dark) {} with the button, without having to create other css classes or other files

You can’t do that, it’s controlled by the browser. That’s similar to saying you would like to enable @media (min-width: 1000px) {}

thank you, you saved me a few hours of research and testing.

then I will have to implement in addition to this other classes or new css to be replaced with the button toggle

So, when set by the browser you cannot overrule? That’s dumb, there must be a solution

It’s a built in feature as part of the browser. If the operating system is using a dark colour scheme the browser will respect that and provide a flag, prefers-color-scheme: dark, to allow site developers to also respect the users colour scheme preference. Being able to toggle it within the site would be a feature on top of that

1 Like

It would be a great feature

@tvdsluijs you can effectively override the browser and force your site to ignore the user’s browser dark mode settings (make it always be either light or dark or whatever you want) by just NOT providing the alternative dark mode styles.

If a theme already has the darkmode built in, as Casper, you can remove it:

I don’t want to remove it. I want my visitors to have an option.

I have manual and automatic mode on https://en.blog.themarfa.name/ and source code of my theme is here GitHub - Marfa/Blogtheme at en . You can use it if you can find how it works :smiley:

I think Ghost using CSS @media (prefers-color-scheme: dark) to automatically set CSS rules is a bad idea.

We can detect OS theme in Javascript. (css - How to detect if the OS is in dark mode in browsers? - Stack Overflow) and then set body class to dark if the user’s OS theme is dark. Otherwise, remove that class.

With that, we can also add a button to change the theme.

What do you think?

I think this is a great technique, but best implemented per use cases that need it :slight_smile:

1 Like

I’m having difficulty adapting my Lyra theme to dark-only. Is there an easy solution that I could implement for that theme?