Dark mode
This blog now has an option to enable a “dark mode”. Meaning, you can see everything on a dark background. Just click or tap the checkbox next to the little moon (🌙) in the top right corner. Your browser will remember the setting the next time you visit – which I hope you will.
The dark background is much gentler on the eyes when looking at your screen in a dark surrounding and generally nicer for looking at photos. And since that’s the content I post most frequently, I might even make this “dark mode” the default in the future. But for now, it’s an option.
The technical background
I’ve had this separate “dark mode” for a while now. But since it had no user interface (UI) on this site, it could only be discovered and enabled, when the browser recognized alternate stylesheets and itself offered a UI to switch between them. Of the major browsers, I think that’s only Firefox’ desktop version – at least on a Mac. And even then I think most folks don’t know about – or use – this.
Searching online for some help, I found this ancient article by Paul Snowden on the A List Apart website from 2001. While dated, it still was describing pretty much what I wanted: a little script to switch between alternate stylesheets of a website (as opposed to – for example – toggling class names on the <body> tag or something similar). I couldn’t and didn’t want to use the author’s script as is. But the article gave me the hint that <link> and <style> tags have a disabled attribute which I can use to enable or disable them. So off I went to write a little script that does these four things:
- Make the UI visible – in this case a checkbox plus label – to toggle the stylesheets (because in case JavaScript is disabled, there’s no need to render the UI, since you couldn’t use it anyway).
- When the checkbox is toggled, loop through all relevant
<link>and<style>tags and enable or disable styles accordingly to the current setting. - Store the name of the enabled stylesheet in the browser’s
localStorageto be able to retrieve the preference for future visits (and further navigation). - Read the preference from
localStorageon page load to enable the visitor’s preferred style.
Here’s the whole script:
function switchStyles(enabledStyleTitle, disabledStyleTitle) {
var links = document.getElementsByTagName("link")
var styles = document.getElementsByTagName("style")
for (var i = 0; i < styles.length; i++) {
if (styles[i].getAttribute("title") == disabledStyleTitle) { styles[i].disabled = true }
else if (styles[i].getAttribute("title") == enabledStyleTitle) { styles[i].disabled = false }
}
for(var i = 0; i < links.length; i++) {
if (links[i].getAttribute("rel").indexOf("style") != -1 && links[i].getAttribute("title") == disabledStyleTitle) { links[i].disabled = true }
// I don't exactly know why I seem to need to "double-toggle" this here. But on WebKit-based browsers, it wouldn't apply the appropriate style on first page load. And this seems to do the trick.
else if (links[i].getAttribute("rel").indexOf("style") != -1 && links[i].getAttribute("title") == enabledStyleTitle) { links[i].disabled = false; links[i].disabled = true; links[i].disabled = false; }
}
localStorage.preferredStyle = enabledStyleTitle
}
function switchStylesBasedOnChecked() {
if (styleSwitchCheckbox.checked) {
switchStyles("Dark", "Light (default)")
} else {
switchStyles("Light (default)", "Dark")
}
}
// START HERE
var styleSwitchCheckbox = document.getElementById("style-switch")
styleSwitchCheckbox.parentElement.style.visibility = 'visible'
// simply "check" the checkbox when the user's stored preference was "Dark"
if (localStorage.preferredStyle == "Dark") { styleSwitchCheckbox.checked = true }
// On page load, making sure the correct setting is applied
switchStylesBasedOnChecked()
// Whenever the checkbox changes, switch styles again
styleSwitchCheckbox.addEventListener('change', function(event) { switchStylesBasedOnChecked() })
Feel free to use this script yourself – unmodified or modified.
I also like to high-five the person or team who was responsible for the localStorage API. So straightforward, I almost couldn’t believe it.