Dark mode in a website with CSS(tombrow.com) |
Dark mode in a website with CSS(tombrow.com) |
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?
Don't get me wrong - I quite enjoy dark mode most of the time, but why now and not earlier?
https://android-developers.googleblog.com/2012/01/holo-every...
I’m guessing a few people finally decided to do it in other places.
I tested it a month ago and figured an update was coming soon. But I just tested it again on iOS 13.1 with everything up to date and still no luck. Safari works as my control.
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.
* 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.
(It doesn't seem to have occurred to that author to try reducing the brightness of the images, or reducing saturation with the saturate() instead of grayscale(), but those also seem worth trying, brightness in particular.)
Apple's Smart Invert is even simpler, it just leaves media like images and video as-is, only inverting colors of other things.
I suppose for diagrams that you know are black-on-white, inversion is nice, but it should be opt-in.
> Solution: filter: invert(1) hue-rotate(180deg);
This might be nominally acceptable, but it’s going to be pretty mediocre. Both of these methods dramatically distort color relationships from the original.
Getting someone to explicitly pick colors that work in dark mode will yield much better results. (Of course, takes a lot more manual work by an expert, instead of a few automatic text replacements.)
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."
You'd never define a particular color, just algorithms for taking some input color and deriving each needed color from that one.
Then the user can say: "I want this file in blue and this one in orange" and the syntax highlighting still calls out the features in a relative way but the absolute colors are used as cues for something else (like test coverage or something from source control).
Ok, maybe doing UI's would be fun after all.
This sucks when you want then share the diagram with someone, on certain platforms the diagram will be unreadable due to the lack of contrasting background.
- 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.
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.
This is an interesting choice. While it might be easier on the eyes, personally it feels kind of icky to change colors on images…
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.
Though regular photos (and videos) are rarely so bright that it hurts the eyes while in a dark environment, unlike diagrams and other kinds of drawings, which can easily be mostly white.
> UI chrome
Versus
> Chrome UI
Works great.
document.body.style.filter = "invert(1)";
document.body.style.backgroundColor = "#141414";
I use a fine tuned custom stylesheet with Stylus chrome extension.https://github.com/darkreader/darkreader
https://github.com/openstyles/stylus (not built into release yet)
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...
I wrote about it here: https://carlschwan.eu/2019/07/12/new-userbase.html
I didn't do the "dimmer images" thing, but I'll try it sometimes.
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?
https://medium.com/@mwichary/dark-theme-in-a-day-3518dde2955...
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.
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).
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.
I wrote about it at https://chrismorgan.info/blog/dark-theme-implementation/.
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%); }'; })();
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.
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.
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).
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.
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.
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=...
Only problem - that is not what the market wants. Client: "why did you not implement the scrollbar-hijack/moving-blinking-text!?!?"
And then imagine if your web site is multilingual...
Or use the same dark colors for mobile-size and desktop-size in responsive, but still need to test it to make sure I got all the <div>s that appear in mobile-size but get hidden and/or replaced by other <div>s in desktop-size and vice-versa.
Or discover we thought we'd covered everything, but when you use the normally-touch interface with a trackpad on Chromebooks, the default hover state is still light-mode.
Etc.
- content hierarchy (what's important on one platform will rarely change between other platforms, despite the developer guessing otherwise)
- interactivity (the platform can most of the time cater to the differences in input if you lean on the platform capabilities)
- style
- Iterate and Perfect on the 48 versions
My suggestion of still using classes doesn't eliminate centralization of config, it just means moving the dark mode CSS outside of the media query and into a class, and adding a couple lines of Javascript.
For instance, the first version of Tweetbot for iOS 13 wouldn't allow you to choose a dark theme if iOS was set to use a light theme.
This was quite frustrating because I like Safari in light mode, but I like Tweetbot, iBooks, Kindle, etc in dark mode. This always has always worked and I'd see a different behaviour as a regression. That said Tweetbot fixed the issue very quickly (in a day).
There's normally a little more to it than that, but there shouldn't ever be _much_ more, custom properties are fully dynamic
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.
Also I made a small mistake in the code there, it's `isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches`
If we want to support dark mode now we have to support four different options. Writing that with a combination of classes and media queries is going to be a nightmare:
.default-theme h2 { background: white; color: black }
.inverted-theme h2 { background: black; color: white }
@media (prefers-color-scheme: dark) {
.default-theme h2 { background: black; color: white }
.inverted-theme h2 { background: white; color: black }
}
Your trick might make this a little more palatable.Sorry, I missed the "without changing their Operating System preferences". I agree with another sibling comment here: that seems like bad practice.
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.
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'.
One of the upcoming posts is going to cover handling dark mode for <canvas> content. So far I've just used transparent backgrounds with no black or white drawing so that it's visible either way.
Not much on it yet, just been slowly working through the setup for doing a canvas with a responsive site.
Neat tidbit - the logo image is a single SVG in shades of dark gray, which doesn't work well on a dark background. You can apply image transformations in CSS under the dark mode media query to adapt things like this:
img#wi-logo {
filter: invert(100%) brightness(110%);
}
This is the same tool that the linked post uses for desaturating images, but adding that invert is a useful tool for dark mode. Personally I wouldn't recommend general image desaturation, photos taking more focus against a dark background is a good look if you ask me. At least consider making it an opt-in setting instead of the default.The logo design itself is really slick, though!
It defaults to the light version and then switches to the dark them on request.
This is so people who don't care or aren't good with computers get the light version and those that can set the system theme have the option of getting the dark version.
I've used CSS variables though, which make it even simpler. E.g. I have `--page-background-color` and `--text-color-primary` that are set to a certain default value. In dark mode, these variables are set to other values, removing the need to redefine the actual selectors.
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.
Sadly Safari's API isn't that great compared to those found in Chrome/Firefox; there's no way to catch the url before the page actually loads. I inject some JS to catch and redirect as fast as possible, but sometimes you'll see a flash of the new Reddit experience. If a better API becomes available at some point I'd gladly swap it out. :)
I borrowed a coworker's iPad at lunch and fixed this bug.
As best as I can tell Safari wasn't respecting the text-align: right; CSS rule. I've switched to a flexbox layout for those elements.
https://raw.githubusercontent.com/kristofferR/userstyles/mas...
You can also force Firefox, via an about:config setting to act as if you were using dark mode.
I think it was a bad choice on the browsers' part. It's a totally abdication of the browser's responsibility to render things nicely and configurably for the user. Worse, javascript is bundled malware: you're letting websites execute arbitrary code on the user's machine.
Tracking, terrible website accessibility, and various dark patterns are a direct result of this. Instead of forcing websites to conform to a document format and giving users control over how that document behaves and is rendered, browsers given those powers to websites, and unsurprisingly, this has resulted in user-hostile behaviors. And it's not all peachy for websites either: websites can do a lot more with CSS/JS, but websites also have to do a lot more.
One of my side projects is a web browser which accepts various document types (i.e. image, slide show, article, login form) and renders them. Style/behavior is configurable by the user when possible, but the site serving the document has no control over styling/behavior--they only get to serve up documents which conform to the semantics of the document type. I doubt this will ever take off, but it's been an interesting and fun project so far.
Trade-off is slightly more data to send with each page, since you have to inline the SVG rather than having it cached after the first load. But it's a whole 2kb and could probably be smaller if I wanted to look into SVG optimization.
I would tend towards ease of configuration and consistency, and would only make exceptions for apps/sites with more theme choices than just light/dark.
Whereas for apps with lots of text (e.g. Kindle etc) dark mode looks better (to me).
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
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.
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. :)
If your app really just has light and dark theme choices, you should get rid of the toggle and move all your dark class styles into the prefers-color-scheme:dark media query instead.
You want the user to have less freedom? Great, good luck with your app development, but I sure hope you're not in charge of developing anything I use.
Also if you read my original comment you would've seen that I am still reading the OS setting. The difference is that rather than locking the user into their OS's setting, I default to the OS's setting and give the user the freedom to change it as they see fit.
1) User toggles OS to light, is your site going to switch back?
2) User toggles site to light, and back to dark to see what that does, now there's a persisted app setting. User later realizes they don’t like dark, toggles OS to light, and then has to think about your app's unique way of toggling it back.
To me, that's just unwieldy for very little gain. Why would I want your app to be inconsistent with everything else, other than a poorly executed dark mode?
While there’s a good chance you won't be using my current apps, I’m confident I won’t be the only one to reach a similar conclusion, so you'll likely have to get used to the behavior.
Which is better you can compare
Here's before dark mode
https://codepen.io/greggman/full/vYYOxjd
Here's leaving the backgrounds to the diagrams white
https://codepen.io/greggman/full/zYYGZWB
And here's the hue rotated solution
https://codepen.io/greggman/full/abbOJYB
The ideal solution would be to make all the diagrams twice but that's a ton of work if your site has lots of diagrams. Of course it's all an opinion. I don't have time to redo all the diagrams or go make them CSS styled indivdually so this is the solution I chose for now.
I never saw any assertion that the user must manage apps individually, only that they should be able to. Easy way to do that - by default, the app echoes the system setting. If and only if the user manually changes the setting, does it diverge from that. Somewhat simple way around having a persistent setting get stuck - if the user switches back from the opposite mode, then you go back into "system" mode. So really, instead of needing two toggles, you would have one that has two states - "Respect system setting" and "Use the opposite mode from the system" (which probably need to be worded way better). The only snafu there that I can think of, off the top of my head, would be that if the user changes the system setting, the app state would likewise change.
It's also completely valid if someone doesn't wish to use system-wide dark mode (say, due to specific applications they use that may not function or render correctly in dark mode) but yet wishes to have specific apps in dark mode. I run Windows, which does have a dark mode nowadays, but that only works for certain apps that specifically use it (Windows Explorer does, not that I use that, along with many of the "modern" style apps that ship with Windows), and yet in apps like Discord I still prefer to use the dark mode, and I also have a dark mode extension for my browser.
For what it's worth, the site did correctly detect my dark mode setting in Windows, and display the dark style. As well, I don't necessarily disagree with any developer that does wish to exclusively use the system setting. However, I do see room for both approaches.
Sorry, what? I feel like this is a very contrived reason to support dark mode in your interface, if it even helps…
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:
She spent her time on Twitter because it has a terrific dark mode. She couldn't get other things to work for her.
So people who are very photophobic are apparently not finding adequate accommodation for their needs. I poked around a bit after talking to her and confirmed that her criticisms were valid. The current available options don't work well for trying to surf the internet under such constraints.
I'm not advocating that anyone do anything in particular. I'm just talking about use cases I have a little knowledge of. That's it.
Because I do. And I'm someone who runs permanent dark mode via plugins in firefox due to eye strain/headaches. I don't expect the world to bend over backwards and I certainly don't expect people to recolour image backgrounds for me. The plugins do a good enough job.
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.
That's really good info.