Hacker News new | ask | show | jobs
by chrismorgan 2353 days ago
The actual code behind this is short and straightforward: https://github.com/ColinEspinas/darken/blob/master/src/index.... For myself, I think it gets the balance of complexity wrong: it focuses on shifting various things into JavaScript, rather than doing it all in CSS using the (prefers-color-scheme) media query, and rewriting media queries to achieve manual switching.

As a demonstration of the alternative approach I advocate, see what I came up with for my own website: https://chrismorgan.info/blog/dark-theme-implementation/. This uses native CSS techniques, working completely without JavaScript, merely using JavaScript to allow the user to manually switch, retaining that preference for future page loads and optimising page loading just about as far as is possible when doing it client-side to minimise the probability of a flash of inverted content if you manually switched to the opposite of what (prefers-color-scheme) would have chosen.

The main thing that my approach doesn’t do that this thing does is dispatching an event, so that other JavaScript could conveniently be notified of a theme change. This is fairly deliberate on my part (I deliberately do all theme switching with CSS, and have no JavaScript that needs to change anything for dark mode), but could readily be added to what I wrote if desired.

With my approach (for which I will also clarify that the JavaScript is deliberately written for compactness, not some theoretical notion of maintainability or extensibility), the example:

  <button id="dm-toggle">Toggle darkmode</button>
  <script>
    const darkmode = new darken({
      toggle: "#dm-toggle",
      variables: {
        "--primary-color": ["#ffffff", "#000000"],
        "--secondary-color": ["#000000", "#ffffff"],
      }
    });
  </script>
… would be written more like this:

  <script>
    // (Add the button to the document in JS,
    // since it’ll only work if this JS runs anyway.)
  </script>
  <style>
    body {
      --primary-color: #ffffff;
      --secondary-color: #000000;
    }
  </style>
  <style media="screen and (prefers-color-scheme: dark)">
    body {
      --primary-color: #000000;
      --secondary-color: #ffffff;
    }
  </style>
(Two style blocks because my thing doesn’t deal with `@media … { … }` inline in CSS, because I don’t need it. You could make it do it if you really wanted to.)

I find this approach much more manageable, and it allows adding custom CSS rules for dark mode (which I definitely use), rather than just setting CSS custom properties.

2 comments

Very interesting thanks. I'm looking for a balance in great UX and features with a minimalist approach to the code needed in the client. Trying to stay with vanilla javascript with little dependencies might be hard thougg. So many frameworks and old habits. Maybe wasm will change that.
I understand the concept of what you are doing, but I think those two methods have different use cases, yours may be more performant but mine, I feel, is more simple for everyday usage. I'll definitly look your work more in depth. Thanks for the feedback!
I was also a bit confused as to why the title was "DarkMode Made Easy", especially since your example just showed adjusting CSS variables. I would assume anyone who's working with CSS variables, also knows about media queries, so it's far easier to just do it all in CSS.

Where I could see this being useful is that you have a callback that you can use, so when dark mode is enabled, you can make some other adjustments when needed.

You'll have a callback on the next version. I plan a lot of tweaks and features that can hardly be done only in CSS, moreover the plan is to give devs an easy way to do dark-modes. I understand the divergences and critics but want to try things as a student. I thanks you a lot for your review.
Don’t get me wrong, it’s great. Just that with the current examples it’s not that useful to me. Callbacks would be cool!
I honestly recommend writing your own. The code is presently close to trivial, and if you write such a thing yourself you can take it in the direction that suits your requirements.