Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

How to toggle? #22

Open
nicolaipre opened this issue Feb 9, 2020 · 5 comments
Open

How to toggle? #22

nicolaipre opened this issue Feb 9, 2020 · 5 comments

Comments

@nicolaipre
Copy link

Hi.

This is probably extremely simple but I just cannot seem to figure it out.

I am trying to make a button that lets me toggle between dark and light mode on my web site.

I cannot seem to figure out how to do it. It works fine from chrome console and emulating CSS prefers-color-scheme in the Rendering console, but I want a JavaScript button to do this.

How can I set the browsers prefers-color-scheme value using JavaScript? I can only find methods on how to detect which color scheme is currently in use, but not for SETTING it.

Do I have to set "user-color-scheme" in localstorage or something?

@juliomotol
Copy link

This package doesn't include any JavaScript logic to toggle between schemes. It uses CSS to detect the device's natively preferred color scheme.

=prefers-scheme($scheme)
@media (prefers-color-scheme: $scheme)
@content

If you want to toggle between the color scheme, you'll have to implement that your self. I have tried implementing this but with the cost of drastically increasing the build size, there is a better way to implement this but I'll stick to what I have for now. See my demo or below for reference.

@rajmondx
Copy link

rajmondx commented Jul 25, 2020

Its an ugly solution but it works:

  1. Give your HTMLLinkElement an id e.g. id="dark-theme"
<link id="dark-theme" rel="stylesheet" href="/bulma-prefers-dark.min.css">
  1. Add toggle function
function toggle(){
  let darkLink = document.getElementById('dark-theme');
  if(darkLink){
    darkLink.remove();
  }else{
    darkLink = document.createElement('link');
    darkLink.rel = 'stylesheet';
    darkLink.id = 'dark-theme';
    darkLink.href = '/bulma-prefers-dark.min.css'
    document.head.appendChild(darkLink);
  }
}
  1. Done (the buttom is just info which doesnt matter if you didnt mess up with the default colors)

hint. instead of trusting your browsers caching you could load the css as base64 encoded href.


I suggest not to use the *-dark-classes (e.g. is-primary-dark or is-info-dark).
Tbh it doesnt look bad even if you do, but if you find something which you want to chang e.g. change color of is-info-dark to is-info then just create a css e.g. overwrite-dark.css

.is-info-dark {
  /*original color of .is-info*/
  background-color: #0f81cc; 
}

and adapt the toggle to remove/add overwrite-dark.css

...
let overwriteDark = document.getElementById('dark-theme-overwrite');
if (darkLink) {
  ...
  overwriteDark = document.createElement('link');
  overwriteDark.rel = 'stylesheet';
  overwriteDark.id = 'dark-theme-overwrite';
  overwriteDark.href = '/overwrite-dark.css'
  document.head.appendChild(overwriteDark);
} else {
  ...
  if (overwriteDark) {
    overwriteDark.remove();
  }
}
...

If you are interested in changing css rules "on the fly" e.g. copying existing rules and change some values then you might are interested in getComputedStyles(element). It allows you to get the css rules of an elment.

  1. Collect all css rules, change those you wish and write them in one string (like a file)
  2. Convert that string to base64 (btoa(css))
  3. Add that base64 as href overwriteDark.href=`data:text/css;base64,${base64Css}`;

hint. Of course only do this if you dont care about performance or cache your base64 encoded css.

@Syzygianinfern0
Copy link

Syzygianinfern0 commented Aug 6, 2021

@rajmondx your solution works excellently on Firefox Desktop (Linux) but not on Chrome Desktop (Linux) for me. Although it works on Chrome Mobile (Android). Any idea why?

Edit: It does toggle those stylesheets on Chrome Desktop, but it does not affect the webpage.

2021-08-06.10-54-07.mp4

@Syzygianinfern0
Copy link

Edit 2: Turns out the solution above worked only if the browser was preferring dark mode in the first place. As of now, I do not know how to fix it.

@skrabbenborg
Copy link

I've come to the same conclusion as you have @Syzygianinfern0. In order to do as you wish, you'll need to implement a Javascript toggle that also honors prefers-color-scheme yourself. Bulma-prefers-dark has the media-query incorporated which will hinder you in doing so (as you've found out). You should probably look for an alternative for this theme, or it would be awesome if this theme would be made available without the media-query.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants