DEV Community

Cover image for One line - Dark Mode using CSS
Akhil Arjun
Akhil Arjun

Posted on

One line - Dark Mode using CSS

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);
}


Enter fullscreen mode Exit fullscreen mode

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);
}


Enter fullscreen mode Exit fullscreen mode

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;
}


Enter fullscreen mode Exit fullscreen mode



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

Latest comments (52)

Collapse
 
ankurk91 profile image
Ankur K

Not working well in Firefox desktop

Collapse
 
Sloan, the sloth mascot
Comment deleted
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
 
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
 
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
 
jabo profile image
Jabo

This is amazing!

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
 
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 ❤️

Some comments may only be visible to logged-in visitors. Sign in to view all comments.