
Dark mode in a website with CSS - teaspoon
https://tombrow.com/dark-mode-website-css
======
greggman2
I recently added dark-mode support to a few sites. It took way more time then
I thought it would. At first I thought "oh just add a few lines off CSS" but
then ...

* Some diagrams had white backgrounds

Solution: remove the backgrounds so they are transparent

* Most diagrams had black lines/arrows which didn't look good on dark gray backgrounds

Solution: use CSS filter:invert for images

* Some images are photos not diagrams so inverting their colors doesn't work

Solution: Use a selector for svg only img[src$=.svg] and a class when manually
needed

* Some svg diagrams have their colors referred to like "see the red object" in that text.

Solution: filter: invert(1) hue-rotate(180deg);

That makes the blacks become white but the colors kind of stay the same hues
at least

* The are many interactive digrams on the sites.

Solution: All of those had to be refactored to not use hard coded colors but
do something like

    
    
        const darkMatcher = window.matchMedia("(prefers-color-scheme: dark)");
        const isDarkMode = darkMatcher.matches;
        const colors = isDarkMode ? darkColors : lightColors;
    

And draw everything with the appropriate colors. Its up to you if you want to
trigger re-drawing if the user changes their preference

* Some text was color coded for to match the diagrams as in
    
    
        <span style="color: red;">x-axis"</span>
    

But now those colors looked bad on a dark background.

Even 5 months later I still find places I missed.

~~~
chadlavi
Why mess with content colors? Just leave the images.

~~~
DoreenMichele
If you have a lot of images with white backgrounds, that's going to defeat the
purpose of Dark Mode.

Some people prefer dark mode because they suffer migraines and bright lights
are a problem when they have a migraine. Or homeless people may be using it
for both stealth purposes and battery conservation when they have limited
opportunities to recharge.

For some people, this preference is not just some minor detail. It's a much
more important thing than "I just happen to like dark color schemes."

~~~
saagarjha
> Or homeless people may be using it for both stealth purposes and battery
> conservation when they have limited opportunities to recharge.

Sorry, what? I feel like this is a very contrived reason to support dark mode
in your interface, if it even helps…

~~~
DoreenMichele
Contrived: deliberately created rather than arising naturally or
spontaneously. Synonym: deliberate

created or arranged in a way that seems artificial and unrealistic. Synonym:
forced

\----

People can do anything they want with their websites. I'm not anyone who sets
global policy on what your website should do.

But there's nothing contrived about the comment. It's an unplanned,
spontaneous thought based on first-hand experience.

I spent nearly six years homeless. I'm quite open about that. I still blog
about homelessness.

I spent a lot of time online while homeless. This was written about me:

[http://alexandralindelof.com/story-
package/](http://alexandralindelof.com/story-package/)

~~~
saagarjha
I'm aware of that, but images on a website being desaturated or having a dark
background doesn't seem like it would help. (I do agree with your appeal to
those who are sensitive to bright lights, FWIW. It's just that this one sounds
like a bit of a reach.)

~~~
DoreenMichele
If you are illegally camped in a dark field and your phone, tablet or laptop
is the only source of light, bright white images emit much more light that can
give away your position than dark ones.

IIRC, the two primary things we did to conserve battery power were 1. Avoid
certain games and 2. Turn down screen brightness.

In ordinary usage, the screen on our tablets was typically the biggest drain
on the battery. This was especially true for tablets with a large screen.

I don't have (anec)data specific to dark mode on websites and power usage. I
just know that using our devices carefully was the difference being kept
occupied for three or four hours until we could sleep or running out after an
hour and having nothing to do but talk, which is not a stealthy activity.

~~~
qplex
"As an example, one commercial QVGA OLED display consumes 0.3 watts while
showing white text on a black background, but more than 0.7 watts showing
black text on a white background, while an LCD may consume only a constant
0.35 watts regardless of what is being shown on screen."

[https://en.m.wikipedia.org/wiki/AMOLED](https://en.m.wikipedia.org/wiki/AMOLED)

~~~
cerberusss
The citation was from 2009. I expect, or rather hope, that things have
improved. Interesting link, by the way, and very useful to add to the
discussion.

------
crazygringo
I love dark mode as a user, but as a developer it terrifies me how much
complexity is involved in programming in 2019. At a stroke, it _doubles_ the
number of possible combinations of:

\- 2 device sizes: desktop vs mobile (e.g. responsive)

\- 3 platforms: web vs iOS vs Android, or web vs Windows vs macOS vs Linux
(not even counting cross-browser or OS version quirks), or god forbid all of
the above

\- 2 input methods: hover/click/drag vs tap/hold/swipe

\- 2 modes for accessibility: full visual+audio vs screenreader/captioned

\- And now 2 visual modes: light vs dark

That's _48_ combinations to design and test for. I'm probably forgetting some
too. But as a developer it makes just the _baseline cost_ of any basic app _so
damned high_.

Again, as a user I love it. But the entrance cost for entrepreneurs, or even
hobbyists? Man oh man.

~~~
laughinghan
Conversely, that's what's amazing about the Web, right?

Whenever people introduce any of those things, like when iOS was introduced,
they had to decide how to port all the existing content and interactions and
widgets to mobile and touch interfaces. As a result, if an entrepreneur or
hobbyist makes an app on one platform and wants it to be at least minimally
usable on another platform, the Web way, way lowers the barrier to make that
jump.

~~~
ken
The particular methods for making CSS backwards compatible are specific to the
web, but the general problems faced by having user display preferences are
not. Adding these features to native apps blows up your testing matrix there,
too.

In many ways, it's even worse. I've got OS settings here for "increase
contrast", "reduce transparency", "use grayscale", "invert colors", and
(because areas of native windows can be translucent) even the desktop
wallpaper comes into play.

I turned on dark-mode for testing my own app, and I had to turn it off because
there's parts of Xcode where the contrast ratio is less than 1.1:1.0. The text
is downright invisible. Obviously nobody at Apple would ever intentionally
make software like that. They must have simply never thought to test with the
same settings as I have.

[https://pbs.twimg.com/media/D1kfN6SUcAEwWxq?format=png&name=...](https://pbs.twimg.com/media/D1kfN6SUcAEwWxq?format=png&name=small)

~~~
laughinghan
And yet Xcode is very successful and well-liked, or at least if it's hated,
it's not for the flaw you found.

Doubtless many, many other apps have also made that same mistake, yet I highly
doubt it has made the difference between success and failure for even a single
one of them.

All of those OS features were introduced to help people, because people wanted
them, some even needed them. I don't think we live in a worse world for having
them, and I believe that dealing with features like those would actually be
even harder in a world without the Web.

------
JDiculous
The problem is that this doesn't let the user toggle dark mode on/off.

If you want the user to be able to toggle dark mode on your site without
changing their Operating System preferences, then you'll need to implement
your dark theme as a class (eg. body.theme-dark) since there's no way to
dynamically set the media query.

    
    
      const darkMode = window.matchMedia('(prefers-color-scheme: dark)')
      if (darkMode) {
        document.body.classList.add('theme-dark')
      }
    

If you have to write your dark theme CSS as a separate class, then there's no
sense in duplicating that logic inside the media query and having to override
it when the user toggles it. So I ended up using that Javascript instead of
putting the styles in the media query.

It's a shame, I would've preferred a pure HTML/CSS solution.

~~~
fastball
Is there anything which allows user choice (i.e. state) that doesn't involve
JS?

~~~
agret
Yes, although doing things without JS is old school web. I think you'd be hard
pressed to find any clients that don't support JS in this era.

Anyway, to accomplish this you would split your styles into seperate CSS files
and then have a drop-down that does an HTTP POST/GET to a server side script
that will then set a cookie on your browser with your preferred choice.

Each time a request comes in from the client you just check that cookie for
which style they want and then change the HTML that's sent to include a
different stylesheet.

~~~
nine_k
There's a number of _end users_ who would like to avoid JS on non-app sites.

------
saagarjha
> Photographs also looked harsh. It turns out that many people prefer images,
> too, to be desaturated in dark mode

This is an interesting choice. While it might be easier on the eyes,
personally it feels kind of icky to change colors on images…

~~~
ubercow13
Yeah that seems bad. If you choose low contrast fonts, reduce the contrast of
photographs to the background by making them darker, etc, it's just like
turning down the brightness and contrast of your whole site. If the user
thinks the content of your site is still too bright with dark mode on, maybe
they should turn down the brightness of their device?

By making everything on your site dark and low-contrast, the implication is
that the user wants to see other things on the screen in higher contrast
alongside your site, like the UI chrome. That seems unlikely - your site is
the most important content that they have on the screen at that time and it
should probably have the highest brightness or contrast of anything on the
screen, not the lowest.

------
Y-bar
I’m probably not representative of the general dark mode user, I think, but I
enable dark mode because I want the UI chrome out of the way to concentrate on
the content. I don’t want dark content. Is there a way to disable this media
query?

~~~
OJFord
Ditto. Duckduckgo seems to have added support, but has a preference to keep it
light. I enabled light (despite system dark for reason above) but it means any
new tab search flashes dark for a fraction of a second, before it reads the
lightness preference cookie or whatever.

~~~
saagarjha
Annoyingly, DuckDuckGo doesn't let me set an adaptive theme if I change the
font settings, plus they don't have an easy way to contact them either…

------
brundolf
I did this recently for my new personal website! It's quite easy and really
satisfying. I love doing as much as possible in stateless CSS instead of
JavaScript.

[http://www.brandonsmith.ninja/](http://www.brandonsmith.ninja/)

~~~
Klonoar
Did this about six months ago over at my site. Was annoying to get it right
but glad I did.

Some people find these kinds of sites pointless these days, but I enjoy
keeping one even if I rarely update it anymore. Spirit of the web and all
that.

[https://rymc.io/](https://rymc.io/)

~~~
OJFord
Nice site, it works well on mobile, which is a bit of a pleasant surprise when
it happens from personal blogs etc.!

FWIW the Twitter feed from, I assume, people you follow is a little odd though
- it's not immediately clear that it's not you, nor about the article being
viewed, which it doesn't necessarily have anything to do with, and it includes
replies to threads. At the time of writing the top one is recommended reading
that's 'racist from the start'.

~~~
Klonoar
Yeah, it bleeds a bit too much on mobile - younger brother passed away
recently and I shoved the site out the door before heading back home to be
with him. Desktop view has it more marked as separate content - e.g, that
tweet is actually a Retweet with a comment, which is kind of a pain in the ass
to handle from Twitter's API. Should find time to clear it up a bit I guess.

Site works well on mobile because I cannot stand sites that don't load quick +
layout well on mobile, and considering the general content I post, I'd expect
the audience to have the (relatively) same pet peeve.

I open sourced the activity scraper as well, if anyone's interested:
[https://github.com/ryanmcgrath/activity-
scraper](https://github.com/ryanmcgrath/activity-scraper)

~~~
agret
Looking at the feed you should see if it's possible to exclude any tweets that
begin with "RT" (retweets) or the "@" (replies). This way only posts you write
should show in the feed, would make it much cleaner as without the full
conversation contexts those other messages make no sense.

The GitHub activity feed is pulling in every comment you make, see if you can
filter that to only show pull requests you've created to showcase your work.
Maybe also include commits to your own projects if the commit length is more
than a certain number of characters to filter out the small updates.

~~~
Klonoar
Heh, I should be clear: I consider the aforementioned Tweet/RT issue a UI/UX
thing, it's otherwise working as designed.

I'm perfectly happy showing my @replies, rando GitHub activity, etc. Nobody is
actually reading that sidebar, short of a select few - I like having that junk
indexed in search engines attributed to my own domain.

It's free real estate. :)

------
cbsks
Now if only Hacker News would implement it!

~~~
skunkworker
I currently use 'DARK READER' for hacker news and it works quite well using
the 'Filter+' theme engine.

~~~
ehsankia
I use the following: [https://userstyles.org/styles/113994/hacker-news-
dark](https://userstyles.org/styles/113994/hacker-news-dark)

Works great.

~~~
kristofferR
I've put an updated version here. This updated version is an UserCSS, which
means it can be automatically enabled/disabled based on system Dark Mode
setting.

[https://raw.githubusercontent.com/kristofferR/userstyles/mas...](https://raw.githubusercontent.com/kristofferR/userstyles/master/HackerNews-
Dark/HackerNews-Dark.user.css)

~~~
ehsankia
Awesome, and I see you fixed the vote button colors.

------
kristofferR
The two best Dark Mode extensions just implemented automatic Dark Mode support
(so the web goes dark automatically when Dark Mode is enabled) :D

[https://github.com/darkreader/darkreader](https://github.com/darkreader/darkreader)

[https://github.com/openstyles/stylus](https://github.com/openstyles/stylus)
(not built into release yet)

~~~
least
I like DarkReader, but it's been a huge exercise in patience seeing Firefox
and Chrome getting all the updates, while the paid Safari version languishes.

By the extension author's own admission [1], the majority of the revenue comes
from the Safari extension, but he still prioritizes the (I imagine) larger
user base of the firfox and chrome extensions. It's frustrating, to say the
least.

[1]
[https://github.com/darkreader/darkreader/issues/1205#issueco...](https://github.com/darkreader/darkreader/issues/1205#issuecomment-477282237)

------
ognarb
I did this for the KDE wikis {userbase,techbase,community}.kde.org, this was a
lot harder than I first thought, because of the amount of user contributed
content with white background, hardcoded color in the text.

I wrote about it here: [https://carlschwan.eu/2019/07/12/new-
userbase.html](https://carlschwan.eu/2019/07/12/new-userbase.html)

------
louismerlin
I baked dark mode into my css microframework [0], and it's always so
satisfying to see people using it !

I didn't do the "dimmer images" thing, but I'll try it sometimes.

[0] [https://concrete.style](https://concrete.style)

~~~
pspeter3
That's a great micro framework

------
jfengel
I apologize for my ignorance, but could somebody explain the need for dark
mode? I know that it's bad to have a phone glow in your face when your eyes
are adjusted to the dark, but don't most phones automatically lower the
brightness? That seems to work well enough for me. Perhaps a specific dark
mode could do it better, if well designed, but most sites have a hard enough
time doing one good color scheme.

I know some people would prefer a light-on-dark color scheme in general, even
during the day. Is this entirely about what you see in the dark, or is there a
component of wanting more "skins" in general?

~~~
teaspoon
There's a good discussion of "why dark mode" in the article that mine links
to: [https://web.dev/prefers-color-scheme#why-dark-
mode](https://web.dev/prefers-color-scheme#why-dark-mode)

~~~
jfengel
Thank you.

------
uallo
Here is another article that goes much deeper into how to actually use CSS to
implement the dark mode. While it does not rely on the media query (the
article is almost 17 months old after all), it shows many other CSS features
you could use.

[https://medium.com/@mwichary/dark-theme-in-a-
day-3518dde2955...](https://medium.com/@mwichary/dark-theme-in-a-
day-3518dde2955a)

------
hoseja
If you want to make sure your website is pleasant for dark-browsers, check if
it doesn't break with extensions such as [https://addons.mozilla.org/en-
US/firefox/addon/dark-backgrou...](https://addons.mozilla.org/en-
US/firefox/addon/dark-background-light-text/)

~~~
vovvov
Or similarly for Chrome: [https://chrome.google.com/webstore/detail/dark-
reader/eimadp...](https://chrome.google.com/webstore/detail/dark-
reader/eimadpbcbfnmbkopoojfekhnkhdbieeh)

------
flukus
The problem with all these dark modes is that I end up with 50 shades of grey
and things are harder to distinguish because there's no consistency on where
to apply the various shades.

It's a testament to how primitive the web is as a platform that it can't do
something like apply a universal theme like Windows 3 did.

------
defanor
Sounds like good news, and similar to how Emacs handles it; do newer versions
of web browsers also change the base/default colours when dark mode is used,
by the way?

Still not a complete replacement of global colour overriding (white flashes,
or simply switching between dark and light themes often, can be quite
unpleasant in a dark environment, and of course all the websites won't ever
employ it, and some will use it wrong), but at least from the webmaster side
it should simplify the colour theme decisions quite a bit (which were/are hard
if you care about that sort of thing: I hoped that major web browsers will do
something like that with alternate stylesheets someday, but as a media feature
it would work too).

~~~
comex
> do newer versions of web browsers also change the base/default colours when
> dark mode is used, by the way?

iOS at least does not. Perhaps because some sites customize foreground colors
but not background colors or vice versa, and they’d break if the foreground
wasn’t dark or the background wasn’t light.

------
jordanmiguel
Try accomdating for Dark Mode as an email developer...

~~~
CaptainMarvel
How would you do that?

~~~
jordanmiguel
No way as of yet. At the moment the best bet is to ensure that images
accomodate for dark mode (particulary in email clients such as Outlook).
Hopefully on the future this can be done with a line of CSS -_-

------
chrismorgan
I recently added dark mode support with a new website for myself, using
(prefers-color-scheme: dark) by default, but also allowing the user to switch
between light and dark mode if they have JavaScript enabled. It also supports
switching image sources in dark mode, so that I can use a dark mode screenshot
in dark mode, and light in light. (I haven't yet published the draft article I
have using this feature.)

I wrote about it at [https://chrismorgan.info/blog/dark-theme-
implementation/](https://chrismorgan.info/blog/dark-theme-implementation/).

~~~
tenryuu
SteamDB also recently added this too, but it also doesn't require JavaScript,
as it's based in the cookie. The toggle does use JavaScript if you do have it
enabled

------
pedrocr
So that's why sites have been annoyingly turning dark lately. In Firefox
apparently this can be disabled by creating a new integer preference in
about:config called "ui.systemUsesDarkTheme" and setting it to 0.

------
romdev
I have chrome updates restricted by my organization and can't use this
feature. Instead I'll occasionally use this bookmarklet to invert colors on
very bright pages:

javascript:(function() { var tag = document.createElement('style'); tag.type =
'text/css'; document.getElementsByTagName('head')[0].appendChild(tag); tag[
(typeof document.body.style.WebkitAppearance=='string') ? 'innerText' :
'innerHTML'] = '* { background-color: white !important; color: #444
!important; } html { filter: invert(100%) grayscale(100%); }'; })();

------
tripzilch
> It's recommended to avoid pure white for text, and I chose likewise to avoid
> pure black for the background.

This is such nonsense. Pure black is never pure black on a monitor and neither
is white. And the link he provides just restates the assertion with no
additional reasoning.

See, I get it. If you create work as an artistic statement, you deliberately
pick not-quite-blacks/whites because the defaults are not your artistic
choices if you just default to them.

However, once you take this as a given rule and you pick some not-quite-white
because "it is recommended", that defeats the entire purpose.

------
lostmsu
Does not seem to work in Firefox for Android.

~~~
_bxg1
Do you have Android's dark mode enabled, and is your Firefox up to date? It's
a pretty new CSS feature

~~~
354896547981565
Doesn't work for me either. Android 10, Firefox 68.1.1 and Chrome 77.0, dark
mode activated.

~~~
_bxg1
Weird. It's supposed to work on Android Firefox 68; Chrome 77 is unclear:

[https://caniuse.com/#search=prefers-color-
scheme](https://caniuse.com/#search=prefers-color-scheme)

------
skykooler
How does one enable this setting in Firefox?

~~~
_bxg1
It's OS-level. macOS, iOS, Android, and I believe Windows 10 will all send
this signal now to whichever (modern) browser you're using.

~~~
lol768
As will Linux/Gnome.

~~~
skykooler
Any idea how to set this on Ubuntu? I have what I assume is the dark theme -
title bars are white text on dark grey background - but this website displays
a light theme in Firefox.

~~~
lol768
It depends on your Gtk theme, I think. If it's marked as dark, then Firefox
will pick that up and apply the CSS accordingly. I use Yaru-dark.

You can also force Firefox, via an about:config setting to act as if you were
using dark mode.

------
arjunkomath
It's not widely available yet, [https://caniuse.com/#search=prefers-color-
scheme](https://caniuse.com/#search=prefers-color-scheme)

~~~
jacurtis
True, but does it have to be?

The beauty of this setting is that it falls back 100% gracefully. Basically if
your OS and/or browser doesn't support it, then you just see the "normal"
version of the site.

Because Dark Mode is only available on newest versions of most operating
systems, it is also reasonable to assume that the people running a dark mode
compatible device would have a modern browser.

So all-in-all, I think compatibility is a moot issue.

------
eyegor
Slightly off topic,

I find it kind of ironic that there's so much debate surrounding the
intricacies of dark mode support on a forum with no dark mode support (even
though it avoids 90% of the gotchas).

------
ripley12
Shameless plug: I did the same thing to my personal website and wrote about it
with light/dark screenshots: [https://www.reillywood.com/blog/dark-
mode/](https://www.reillywood.com/blog/dark-mode/)

I like working in Solarized Dark, so I wanted my website to serve up Solarized
Dark. I dim images in dark mode too, but I turn them up to full brightness on
hover.

~~~
saagarjha
I only use Solarized for code snippets on my website, but the benefit of using
it as a color scheme is that switching between the two is a one line addition:
only the background needs to respond to prefers-color-scheme.

~~~
ripley12
Yeah, that would be nice for UIs that can use Solarized Light. I experimented
with it as a full UI, but it just didn't look quite right to me – I ended up
only using it for light mode code snippets.

------
m-p-3
One of my (maybe unwarranted) concern with automatic dark mode, is the
potential ability of the browser and apps to determine my (very) coarse
location based on when the dark mode is enabled or not, as it because another
potentially identifying info among others.

Does that kind of CSS allows a script to determine if the browser is
displaying dark mode or not, or send back that information to ads servers?

~~~
teaspoon
Yes, you could craft CSS to conditionally load an image based on the media
query. This would let a server observe the client's setting.

------
qubyte
Naïvely I tried to do this by overriding a few custom properties and using
filters. My site has a position: sticky nav, and filters introduce a stacking
context, so things which filters apply to naturally go on top of the nav when
before they went behind. A minor annoyance, but it demonstrates how
introducing a dark mode isn’t as straight forward as I thought it would be.

------
xfalcox
I wish more stuff was presented also as a header, so you could serve a
specific CSS file for people who prefer dark-mode.

------
barbs
Where did this dark mode craze come from?

Don't get me wrong - I quite enjoy dark mode most of the time, but why now and
not earlier?

~~~
aitchnyu
To speculate, screens are progressing to display dark mode well. I get eye
strain from Jetbrains Pycharm dark theme, the terrible way it renders on my
laptop, so I am holding out now. Holo theme for Android may have accelerated
the trend from 2012.

[https://android-developers.googleblog.com/2012/01/holo-
every...](https://android-developers.googleblog.com/2012/01/holo-
everywhere.html)

------
nodesocket
Doesn’t work in Chrome on iOS 13.1.2 for me. Works in Safari though.

------
alib
Not working on Firefox for iOS. Can anyone else confirm this to be the case?
Looks as though Firefox for iOS does support ‘prefers-color-scheme’ media
query.

~~~
saagarjha
I'm quite surprised, as Firefox on iOS should be using WebKit…has Firefox
linked against the iOS 13 SDK yet?

------
michalf6
I get that you want to avoid pure white, but why avoid pure black though? It
looks gorgeous on an OLED device, blending with the bezels.

------
andy_ppp
I would really love a dark mode for hacker news!

------
oceliker
Can HN implement this one day? A dark mode for this website would be great.

------
mister_hn
Please add IE6 support

------
floatrock
Wikipedia needs this.

yes yes there's browser plugins, but I'd rather not have some rando plugin
potentially reading every site I visit to load a dark mode plugin on the ones
it recognizes.

~~~
Volker-E
You can try [https://en.wikipedia.org/wiki/User:Volker_E._(WMF)/dark-
mode](https://en.wikipedia.org/wiki/User:Volker_E._\(WMF\)/dark-mode) for now.
It's a black/night mode at the moment. And (not yet) an official option with
some technical acceptance issues like lazy-loading, therefore flicker on load.
– I work for the Wikimedia Foundation. This wish has been stated as part of
the Community Wishlist survey 2019.
[https://meta.wikimedia.org/wiki/Community_Wishlist_Survey_20...](https://meta.wikimedia.org/wiki/Community_Wishlist_Survey_2019/Reading/Night_mode)

