DEV Community

Cover image for One line - Dark Mode using CSS

One line - Dark Mode using CSS

Akhil Arjun on August 03, 2020

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! 👾 C...
Collapse
 
sdktalks profile image
Sodeeq Olamide

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

Collapse
 
akhilarjun profile image
Akhil Arjun

Well, they say a magician should never reveal his tricks. Maybe I am just a bad one 😂😀

Collapse
 
technikhil314 profile image
technikhil314

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

Collapse
 
akhilarjun profile image
Akhil Arjun

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

Collapse
 
gavinsykes profile image
Gavin Sykes

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

Thread Thread
 
akhilarjun profile image
Akhil Arjun

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

Collapse
 
technikhil314 profile image
technikhil314

Yeah agreed.

Collapse
 
louislow profile image
Louis Low • Edited

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>
Collapse
 
photocoder profile image
Dimas

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?

Collapse
 
akhilarjun profile image
Akhil Arjun

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);
}
Collapse
 
pau1phi11ips profile image
Paul Phillips

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

Thread Thread
 
akhilarjun profile image
Akhil Arjun

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 😀

Thread Thread
 
photocoder profile image
Dimas

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

Collapse
 
jadercm profile image
Jáder Carvalho de Medeiros

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

Collapse
 
akhilarjun profile image
Akhil Arjun
Collapse
 
akhilarjun profile image
Akhil Arjun

I am writing a post for the javascript side of it too. Will post it today itself 🙂

Collapse
 
jojobyte profile image
jojobyte • Edited

Someone likely mentioned this already, but there seems to be a "gotcha" with Firefox and Edge.

Firefox appears to not apply the filter to the background-color of the html or body element.

And Edge (not that I actually care) wont apply the filter to body but will to html

So these wont work

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

html { background-color: #fff; } /* no luck in firefox, works in Edge */
body { background-color: #fff; } /* no luck in firefox nor in Edge */
Enter fullscreen mode Exit fullscreen mode

Cross-Browser Workaround

Put all your stuff in a wrapper element just under the body.

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

/* create a wrapper element and it works great */
body > .wrapper { background-color: #fff; }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
allestri profile image
Allestri

Hey there !
I'm posting this to warn you about the general visual hierarchy of any app using this no-brainer method.
Your components should never be darker than your background, see this tweet for any references.

twitter.com/steveschoger/status/11...

While I can see some uses cases when this method is simple yet effective, it would strongly suggest anyone reading this to dive into Custom CSS properties and setting up colors scheme by hand, especially when you have a strong color identity and things can spice a little bit by naively inverting those ( accessibility and design issues ).

Collapse
 
mdhesari profile image
Mohammad Fazel

Fantastic!

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

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

Thank you, peace.

Collapse
 
akhilarjun profile image
Akhil Arjun

Hey nopes. Have at it bro 😎✌

Collapse
 
auscompgeek profile image
David Vo

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

Collapse
 
akhilarjun profile image
Akhil Arjun

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

Collapse
 
abhaygawade profile image
Abhay

Voila!

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
akhilarjun profile image
Akhil Arjun

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 😀

Collapse
 
husseinkizz profile image
Hussein Kizz

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?

Collapse
 
lookrain profile image
Lu Yu

nice! how about emojis tho

Collapse
 
elviswang27 profile image
sourcewang

Wonderful !!!

Collapse
 
jabo profile image
Jabo

This is amazing!

Collapse
 
mfcodeworks profile image
Arran Fletcher

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

Collapse
 
akhilarjun profile image
Akhil Arjun

Thats cool! Thanks for that tip ❤️

Collapse
 
braydentw profile image
Brayden W ⚡️

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

Collapse
 
akhilarjun profile image
Akhil Arjun

Cool. Do drop me a link to your portfolio once done. Would love to see it 👾🕺

Collapse
 
ryanjj profile image
Ryan

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

Collapse
 
akhilarjun profile image
Akhil Arjun

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

Collapse
 
stanggt3 profile image
Randy Kline

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

Collapse
 
akhilarjun profile image
Akhil Arjun

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

Collapse
 
nabeen profile image
nabeen

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

Collapse
 
akhilarjun profile image
Akhil Arjun

Do let me know how it goes! 😍

Collapse
 
nemo011 profile image
Nemo

Awesome trick! Thanks Akhil. ☺️

Collapse
 
akhilarjun profile image
Akhil Arjun

You are welcome 🕺

Collapse
 
samuelorobosa profile image
Samuel Amagbakhen

Wonderful post, mate

Collapse
 
akhilarjun profile image
Akhil Arjun

Glad you liked it !! 🕺

Collapse
 
nickwatton profile image
Nick Watton

This is wonderful. So simple. Thank you

Collapse
 
akhilarjun profile image
Akhil Arjun

Am glad it helps 😊

Collapse
 
livetvchannels profile image
Trieu.iv

I'm trying
Thanks 👍

Collapse
 
akhilarjun profile image
Akhil Arjun

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 👍

Collapse
 
rossangus profile image
Ross Angus

This is a wonderful post.

Collapse
 
akhilarjun profile image
Akhil Arjun

Thanks mate 👍

Collapse
 
ankurk91 profile image
Ankur K

Not working well in Firefox desktop

Collapse
 
Sloan, the sloth mascot
Comment deleted