|
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. |