loading...
Cover image for One line - Dark Mode using CSS

One line - Dark Mode using CSS

akhilarjun profile image Akhil Arjun ・2 min read

This is an absolute no-brainer method of converting an already developed website to support dark mode.

Without further ado let's get into it! πŸ‘Ύ

Consider this news application for example


News Peek Light

Now add the magic CSS

html[theme='dark-mode'] {
    filter: invert(1) hue-rotate(180deg);
}

Voila! you are done ✌

Dark mode achieved


News Peek Dark

Explanation

Now let's try and understand what is going on under the hood.

The filter CSS property applies graphical effects like blur or color shift to an element. Filters are commonly used to adjust the rendering of images, backgrounds, and borders. (Reference: MDN Web Docs)

For this dark mode, we would be using two filters namely invert and hue-rotate

invert filter helps to invert the color scheme of the application. So, black becomes white and white becomes black and similarly for all the colors.

hue-rotate filter helps us with all the other colors that are not black and white. Rotating Hue by 180 degrees, we make sure the color theme of the application does not change but just attenuate the colors of it.


comparison


The only catch with this method is, it will also invert all the images in your application. So we will add the same rule to all images to reverse the effect.

html[theme='dark-mode'] img{
    filter: invert(1) hue-rotate(180deg);
}

and we will also add a transition to the HTML element to make sure the transition does not become flashy!

html {
    transition: color 300ms, background-color 300ms;
}



Result:
Dark Mode Example


There we have our Dark mode implemented. Great job guys!

My days are fueled with coffees and only coffees. So I know, you know what we all should do 🀞


Buy Me A Coffee


Well done

Posted on by:

akhilarjun profile

Akhil Arjun

@akhilarjun

I am a passionate front end developer who enjoys immense guilt-pleasure for writing vanilla Javascript.

Discussion

markdown guide
 

Excellent! Could you please share the JavaScript code to toggle between themes as well?

 
 

I am writing a post for the javascript side of it too. Will post it today itself πŸ™‚

 

if you want full greyscale dark mode then use invert(1) greyscalle(1)

 

Yes, but the only downside to it is that even the images go greyscale

 

Would that be such a bad thing? I've always thought having them do that would be pretty cool.

Oh! yes, it would be. I once worked for a client where the dark mode had everything greyscaled. It was awesome 😎 It's just that not every UX would work better that way. So it has to be informed decision

 
 

This is very amazing, I'm surprised to realize to know that achieving dark mode on one's site is simpler than I thought

 

Well, they say a magician should never reveal his tricks. Maybe I am just a bad one πŸ˜‚πŸ˜€

 

Hello!
That is amazing simple decision!
Great! Thank you very much.
But it is also converted all my background images...
Is it exist any option for filter them?

 

Yeah. You have to apply invert filter again on images to re-colorize them and turn back the hue a whole of 180deg.
We can do that by selecting all images so

html[theme='dark-mode'] img{
    filter: invert(1) hue-rotate(180deg);
}
 

I think he was referring to CSS background-image not img's

I get it. Well, there are a couple of ways we can achieve that too. If it is just a div with a background-image set. Then applying filter would not be a problem there, but if that element has some content then the filter might affect it all too. So we might have to check for specialized solutions.
There is a beautiful article on css-tricks regarding the same css-tricks.com/apply-a-filter-to-a....

Hope that helps πŸ˜€

Yes, correct.
I found only the way to add extra "non-dark-mode" class to turn them back...

 

Excellent! Changing themes also can be made with Yogurt Framework based on a web browser or app settings. Read Theme Auto.

<html theme="auto">
  ...
    <!-- e.g. To compensate inverted image -->
    <img theme="auto">
    <!-- e.g. To compensate other inverted elements -->
    <y theme="auto"></y>
    <span theme="auto"></span>
  ...
</html>

And to force the page theme to turn into either dark or light.

<html theme="invert">
  ...
    <!-- e.g. To compensate inverted image -->
    <img theme="invert">
    <!-- e.g. To compensate other inverted elements -->
    <y theme="invert"></y>
    <span theme="invert"></span>
  ...
</html>
 
 

Fantastic!

I shared it on my twitter account (putting credits).

Let me know if there's a copy right problem.

Thank you, peace.

 

Hey nopes. Have at it bro 😎✌

 

you are amazing man, I see another catch, though. When you define img as background in css, it seems that your workaround does not work.

 

Well, there are a couple of ways we can achieve that too.
If it is just a div with a background-image set. Then applying filter would not be a problem there, but if that element has some content then the filter might affect it all too. So we might have to check for specialized solutions.
There is a beautiful article on css-tricks regarding the same css-tricks.com/apply-a-filter-to-a....

Hope that helps πŸ˜€

 

you can probably add other stuff such as :

  img, iframe {
    filter: invert(1) hue-rotate(180deg);
  }

works like a charm, but it should be listed

 

thanks a lot, will read that.

 

Nice demo, to prevent the image temporarily being inverted and avoid having an extra class you can replace the second one with a :not filter

 

Thats cool! Thanks for that tip ❀️

 

Awesome! Would love to use this technique in my portfolio!

 

Cool. Do drop me a link to your portfolio once done. Would love to see it πŸ‘ΎπŸ•Ί

 

Great post! My profile pic looks like a demon but i see your tip about filtering the images. Nice work!

 

Haha πŸ˜…. Do let me know once you are done with it. I would love to see the result 😊

 

What's the performance impact of that filter on different browsers and platforms?

 

It would be a very lomg converstaion. But since we are using transition property on the html block element we can go ahead and addwill-change: transform property to it too.
This will force it into GPU rendering the page and thereby making it smooth

There is a long awesome post in Smashing Magazine for this
smashingmagazine.com/2016/12/gpu-a...

Hope this helps

 

That's really cool. The only thing I noticed is that everything gets really dim as you scroll. When you stop scrolling the brightness picks back up

 

I dont know if that is because of the filter, or just browser settings. I will take a look at it 😊

 

It's amazing:)
I'll try at my site!

 

Do let me know how it goes! 😍

 
 

This is wonderful. So simple. Thank you

 

Am glad it helps 😊

 
 

Do let me know how it goes πŸ™‚
I have used it in a demo application i am. Building for another PWA tutorial
akhilarjun.github.io/news-peek/

Check it out for implementation of the dark mode πŸ‘

 

Awesome trick! Thanks Akhil. ☺️

 

You are welcome πŸ•Ί

 
 

nice! how about emojis tho

 

I have to try this asap! However most of my theme elements are already dark, would turn white with inversion!!!!!!!!!!! husseinkizz.ml any work around?