loading...
Cover image for Dark Mode Switch πŸŒ™ | It's Time to Make It Working! πŸ”†

Dark Mode Switch πŸŒ™ | It's Time to Make It Working! πŸ”†

shadowscientist profile image Shadow Scientist ・7 min read

Hey Dark Mode! here I come! πŸ™ŒπŸΌ (2 Part Series)

1) Making a Dark Mode Switch πŸŒ™, Lightly πŸ”† 2) Dark Mode Switch πŸŒ™ | It's Time to Make It Working! πŸ”†

Hello everyone! πŸ‘‹πŸΌ
Your Shadow is back with another post! Today, we're going to lift up the second part of the morphing Dark Mode Switch, that we made earlier. Also we'll discover why dark mode is so special and when we should turn the lights off, at the very end of the post! 😁

Before we go through the discussion, let's recall how the switch was made.

Making a Dark Mode Switch πŸŒ™, Lightly πŸ”†


Improving the Idea 🧩 β€”β€”

The switch was made using an <input> (which is a checkbox actually, and it's hidden via opacity -> 0) and a div with two nested div and a span element, to symbolize the sun and the moon as light mode and dark mode respectively...

<label>
 <input type="checkbox"/>
 <div class="switch">
  <div></div>
  <div></div>
  <span></span>
 </div>
</label>

...everything was fine enough, but it was lacking a few accessibility, especially for assistive programs, as @konradlinkowski pointed out -



Creating dark theme button like that makes it unaccessible for people with screen readers. :/



So, I was wondering how it could be fixed and @bhansa suggested a neat solution -

Probably, you can add some aria labels and title to the checkbox and update it when it toggles. It is accessible via keyboard though.

Now we're going to apply the solution in our idea and make the switch working! So, Let's get started!

The Improved Idea πŸ’‘ β€”β€”

As we've traced the issues, we can make the difference, πŸ˜‹

<input type="checkbox" aria-label="Turn off the lights!"/>

Here aria-label hits the change. Though we're using <input> (as a checkbox), it's already accessible via keyboard. We attach aria-label attribute with the checkbox in-order to enable it on assistive programs (like screen readers), so the user will hear "Turn off the lights" instead of nothing.

We can even add a title attribute, but I think it's optional because if the user can see the symbols, he can figure out what's happening,

<input type="checkbox" aria-label="Turn off the lights!" title="Switch to Dark Mode"/>

Also we need to add an id (or class) to the checkbox to access it via Javascript, we'll be discovering its usage in the next steps below.

<input id="color_scheme_switch" type="checkbox" aria-label="Turn off the lights!" title="Switch to Dark Mode"/>

Hence aria-label is meant for screen readers only, would you prefer the same text for title and aria-label? πŸ˜€

Basic Planning β€”β€”

So far we've nailed how to create a CSS only Dark Mode Switch, how to make it morphing and how to make it accessible. Now we've a couple of tasks to do,

πŸ”Ή Add makeup for the dark theme

πŸ”Ή Add an event handler that will trigger when user changes the input state from unchecked to checked (and vice versa)

πŸ”Ή Save the color scheme preference for future visits (we've many ways around to do it πŸ˜‰)

πŸ”Ή Add another event (global function, I guess) to know whether the Dark Mode checkbox is checked or not, if so add dark mode makeup

CSS has the power! β€”β€”

There is zero argument that CSS is capable to do almost anything that's required to make a webpage awesome and beautiful. We'd recently discovered the usability of CSS variables in the previous post(s), it's just another one!

The scope is to add default CSS variables, often under html, so the site would act like the light mode is turned on. However, placing them under :root would make them available globally. That's the life saver...

:root{
--bg-color: #FAFAFA; /* comfortable white */
--text-color: #090909; /* smooth black */
--anchor-color: #005AB3; /* bluish */
--highlight-color: #0066CC; /* another blue */

/* some more CSS variables for makeup here */
}

So, we can use it like,

body{
 background-color: var(--bg-color);
}

h1{
 color: var(--text-color);
}

::-moz-selection /* FireFox */
{
  color: var(--highlight-color);
  background: var(--highlight-bg);
}

::selection
{
  color: var(--highlight-color);
  background: var(--highlight-bg);
}

/* ... some more CSS styles here ... */

and so on...

Oops!

I just leaked the color-palette of my upcoming Dribbble shot! 😳

Forget about that, now we got variables for light mode, and we need some for dark mode. But this time, it's wrapped in html[data-color-scheme = "dark"],

html[data-color-scheme = "dark"]{
--bg-color: #090909; /* dark background */
--text-color: #FAFAFA; /* slightly white text */
--anchor-color: #FFFFFF; /* white text */
--highlight-color: #0099FF; /* another blue */

/* some more CSS variables for dark-mode makeup here  */
}

..this is because when we'll change the checkbox input to checked state, an event listener would fire and html's data-color-scheme attribute would be changed to "dark" (or any string) and the dark theme makeup would be applied over the whole page.

Javascript is our friend β€”β€”

The Dark Mode switch has meet all the features it needed to make any website (or app) stunning. We'll go through the Javascript portion.

Add an event handler that will trigger when user changes the input state from unchecked to checked

When user changes the input state, we'll update the data-color-scheme to match it. "dark" for Dark Mode and "light" or " " for Light mode. Actually light mode doesn't need a specification, as it's the default one.

var sw = document.querySelector('#color_scheme_switch');
// or, var sw = document.getElementById('color_scheme_switch');

function changeTheme()
{
if(sw.checked){
 document.documentElement.setAttribute('data-color-scheme', 'dark');
}
else{
 document.documentElement.setAttribute('data-color-scheme', 'light'); // or just empty " "
}    
}

 sw.addEventListener('change', function(){ changeTheme() });

Save the color scheme preference for future visits

Most of the users will pay a repeat visit if your sites can grab their attraction. For that reason, we'll store the preferred color scheme for them. Sounds convenient, right? It'll be stored in the browser only, so we don't need a web server or something like that.

Though we've several ways to do it, but Cookies and LocalStorage seems to be most straight forward for this work. Both of them has its own advantage and disadvantage, hence it's up to you, when you use each of them.

@michelle has covered it already,

Cookies looks like a normal text string. But it is not. So we need to create functions to set and get cookies. You can learn more here.

Simply, it can be done via browser's LocalStorage. Let's update the changeTheme function,

var sw = document.querySelector('#color_scheme_switch');
// or, var sw = document.getElementById('color_scheme_switch');

function changeTheme()
{
if(sw.checked){
 document.documentElement.setAttribute('data-color-scheme', 'dark');
 localStorage.setItem('color_scheme', 'dark');
}
else{
 document.documentElement.setAttribute('data-color-scheme', 'light'); // or just empty " "
 localStorage.setItem('color_scheme', 'light'); // or just empty " "
}    
}

 sw.addEventListener('change', function(){ changeTheme() });

Add another event handler to know whether the Dark Mode checkbox is checked or not, if so add dark mode makeup

Now we're checking if the theme preference is saved, if yes then add the desired color scheme,

var current_scheme = localStorage.getItem('color_scheme');

if(current_scheme)
{
  document.documentElement.setAttribute('data-color-scheme', current_scheme);
  if(current_scheme === 'dark')
  {
   sw.checked = true;
  }
  else{
   sw.checked = false;
  }
}
else{
 // user didn't saved it or he hates dark mode
}

All Together β€”β€”

Once we've reviewed all the steps above, we can apply it anywhere we want, for example,

We can have more fun by animating the color scheme, only with CSS transitions. Like below,

/*some fun*/
*{
  transition:color ease 0.2s, background-color ease 0.2s;
}

What makes Dark Mode so special? β€”β€”

Dark mode is mysterious and has a good number of benefits like,

A cool eye-catching user interface and the best reading experience, white text on black background looks like we're reading text from a blackboard! To be honest, it looks amazing! πŸ‘Œ

Bright screens causes digital eye strain whereas dark mode relies easier and healthier on your eyes.

You won't be temped of insomnia for spending hours of your waking time, staring at computer screens.

Bright screens has a good impact on batteries. They use more energy to produce more brightness while dark mode is dark actually. That's why it causes low energy impact and battery life goes long.

A Reddit user wrote a brilliant comment about the same,
Reddit user's response on the benefits of dark mode

This clearly points out, when we should turn the lights on. πŸ˜„

To wrap it up β€”β€”

Dark mode has always made me curious about the ui, how the graphics would look, how will they behave and so on. Though its still mysterious for me and full of surprises! It's not a trend anymore, it's a necessity and a blessing for programmers, coders and overtime workers who spend a lot of time in front of the bright screen and do their job. We all should start using it.

Fun Fact! πŸ’‘

Did you noticed that the ID of input is CSS?
color_scheme_switch = C.S.S 😸

I hope you've enjoyed the topic, please write me in the discussion, share your thoughts about the idea and help me to improve my writing.

References β€”β€”

πŸ”— LocalStorage vs Cookies: All You Need To Know About Storing JWT Tokens Securely in The Front-End
πŸ”— Please Stop Using Local Storage
πŸ”— JavaScript Cookies
πŸ”— localStorage Property
πŸ”— The Benefits of Dark Mode: Why should you turn off the lights?
πŸ”— Light-on-dark color scheme - Wikipedia
πŸ“Œ Color Palette from Get Emoji and custom

That's all for today! I'll come back with another topic next week.
Thanks for reading. Have a great one! πŸ₯°

Hey Dark Mode! here I come! πŸ™ŒπŸΌ (2 Part Series)

1) Making a Dark Mode Switch πŸŒ™, Lightly πŸ”† 2) Dark Mode Switch πŸŒ™ | It's Time to Make It Working! πŸ”†

Posted on by:

shadowscientist profile

Shadow Scientist

@shadowscientist

An ordinary person with a desire of doing something extra-ordinary. πŸ˜‰

Discussion

markdown guide
 

I like that you use the user preferences for dark mode.

Your "What makes Dark Mode so special?" section has some problems, though, beyond the grammar. I've looked these up in journals due to my own difficulties with the "dark mode" trend. Dark mode isn't necessarily "healthier" and is more difficult to read, ESPECIALLY for those of us with eye abnormalities like myself and my grandmother. It may be easier on the eyes at night (a light beside the monitor is the better choice), but in most cases it doesn't improve productivity in the daytime, it makes it worse because the brain has evolved for dark-on-light efficiency. It doesn't have a measurable effect on insomnia, blue light and our own sleep hygiene choices when it comes to screen-time does. Only OLED displays get a battery boost from dark mode, others (which is most of us) don't.

 

First of all, thank you very much for your valuable feedback. I'm glad you liked the usage of user preferences for enabling dark mode. πŸ™‚

I know I'm younger than you both in experience and knowledge as I'm still a secondary student. But I'd like to explain the words,

Dark mode isn't necessarily "healthier" and is more difficult to read, ESPECIALLY for those of us with eye abnormalities

I learned about it in my school. People with eye abnormalities like myopia or astigmatism can experience halation, creating a foggy or blurry appearance while using light-on-dark in an open yard or in a well-lit room, because of over-dilating. Thus it makes more difficult to read, especially when fonts are well enhanced or have optimizeLegibility enabled.

Even I've myopia and I put on glasses while working or reading, but my problem is just the reverse as I can hardly read black text on white background and suffer from headache and blurry vision. I frequently spend up to 7 hours and sometimes a whole day in front of computer screens with light-on-dark mode enabled to prevent my blurry vision and eye strain. So I thought most of us do so, maybe.

I'm a student. I attend my classes and write up the given lectures from the blackboard. So, I wrote "A cool eye-catching user interface and the best reading experience, white text on black background looks like we're reading text from a blackboard!", from that perspective, I wrote it from my personal experience. I just compared the Dark Mode with blackboards, nothing else.

but in most cases it doesn't improve productivity in the daytime, it makes it worse because the brain has evolved for dark-on-light efficiency

Agreed. If our surroundings are bright enough, Dark Mode is not going to help us, rather it'll command our pupils to dilate more that may cause blurry vision or lazyness. Thus Dark mode is not always a better choice with light-on-dark (bright) surroundings, unless you're used to, like me. But I mentioned the quote (in the post) from a Reddit user to highlight when it's best to turn the lights off.

It doesn't have a measurable effect on insomnia, blue light and our own sleep hygiene choices when it comes to screen-time does

Eyes get less tired at night, so those who frequently read online articles before bed can stick with the content for longer time. [5]

Light profoundly affects the timing of sleep and wakefulness, metabolism, and hormone release. [source: verywellhealth]

Being productive and involved with several duties (plus social media), doesn't help us to maintain our own sleep hygiene, especially for newcomers like me, as we spend a lot of time collecting resources, data, tutorials and so on. So we suffer from insomnia, distractions and other problems. As the article denotes,

artificial light at night can negatively affect the timing of our sleep. Light shifts sleep timing, and light at night can shift our desire for sleep later. This can result in difficulty falling asleep, as occurs with insomnia.

All I meant was that. That's how dark mode could enhance our sleep time, that's probably less brighter, I guess.

Last point about battery saving. I agree that it only applies to OLED or AMOLED. OLED screens are mainly used by Android devices and it's something that we all know in general. So I thought it's no use of adding those information here as well. But I marked in the first part regarding the battery saving mode that "I didn't tried it yet" and it's not a surprise that most of the people would simply ignore it.

Although the article was intended to create a Dark Mode Switch and not the entire dark mode concept, the benifits of dark mode was added like an extension, basically targeted to make people curious about Dark Mode, that's all. It's your personal choice whether you like Dark mode or not.

I learned a lot from you. Thanks for correcting me. I will focus on my grammar now on. πŸ˜‡

I'm sorry if I've annoyed you with the post or anyway. I thought feeling is more important than words.

 

I'm going to give you a big tip: don't put yourself down (you said you know you're younger & less experienced) as an intro because age & experience don't really matter outside of school and you give me a reason not to give you credit for what you do know, not that I'm that kind of person but they're out there. Also, critiques don't mean the reader is annoyed. I apologise if I came off that way, it was unrelated to you if it did come through. I know some things you said were opinion and I didn't mean to sound like I was critiquing those. I got my info from journals, not articles, like what you linked, one is a primary source and one is a secondary and less trustworthy (note: less doesn't mean not) and I do realize that there are papers on both "sides". I also realize there are preferences and I don't hold that against people or I'd never be a good programmer. A part of the reason people might miss info that's not all in the same paragraph is that your tutorial reads more like an article or essay which has a lot of words vs. a more simple walk-through. That, and humans aren't perfect, haha.

Thank you for pointing that, I will be more careful next time. I always welcome critiques because learning isn't limited to a specific age or reputation and as a student, learning is my first and foremost duty. You don't need to apologize to me, we recently discovered how a crowd of developers raise a storm in a cup of tea over Canvas vs WebGL! At least in StackOverflow forums and comments. Healthy debate often results better because both of the parties can learn something from the topic. Also most of the development confusions are solved with discussion and communication.

I agree that articles are secondary source and less trustworthy. But I'm currently familiar with articles and forums and I collect data from that sources. I'll try to follow journals as well. You told that the tutorial reads more like an article or essay which has a lot of words vs. a more simple walk-through and it reminds me a funny incident that happened in my school life.

One day my English teacher told us to write a paragraph on "Community" with minimum 200 words. He announced that it's a surprise test and the best writing would be honoured with special points. So we all tried to write our best and the teacher started to give points. My classmates got their paper back but I didn't get mine. I was tensed.

Soon teacher declared the best writing of the day, and it was mine! He asked me to collect my paper and points. I came in front of his desk and the fun began when teacher wrote "-1"(!) on the paper. 😢

I was surprised and asked my teacher why did he gave -1. He replied with a smile that my paragraph exceeded more than 500 words and it's to large to judge as a simple paragraph. Thus he judged an essay in the exam of a paragraph. πŸ˜…

Actually I'm fond of science fiction writings and novels and I love to write them as well. I wrote a few in the past so I thought it'd be better to describe the whole discussion as a story. Thus, old habits die hard. πŸ™‚

 

There is a error in javascript
Uncaught TypeError: Cannot read property 'addEventListener' of null at **.js:34

 

Hi πŸ‘‹ and thank you so much for the feedback. πŸ™‚
I just double checked the Javascript portion but I didn't find any error, console tab is empty on Firefox 79 and Chrome 84. Here is the snapshots:

Chrome
Chrome


FireFox
FireFox


Would you please add some more details like which browser are you using, its version, OS or capture a snapshot with the error in console?

Thank you. πŸ₯°

 
 

Hmm... I checked the public page, but it appears to be working fine as I don't see any error in the console tab, unless the cross-site cookies.

Test in Firefox

But the issue persist on the repository. You might have added the <script src="dark2.js"> source inside head element.

The sw variable was added globally, so it's still invisible in browser's eye and sw = null and eventListeners won't apply on undefined elements. The solution is to add the script tag after the input element or at the very end of the document so that browser would notice the input before it process the script itself. Hope it helps. :)

CodePen always add the script at the very end of the document. So the browser processes the page like CSS --> HTML ---> JS.