Page MenuHomePhabricator

Design UI for turning dark mode on and off
Closed, DeclinedPublic

Description

We need a simple UI for turning dark mode on and off.

Design Goals and Requirements

  • Easy to access: The tool should be close to hand on every page of the wikis. The use case for this is that we believe dark mode will be something users turn on and off frequently.
  • Available to all users, logged in and logged out.
  • Name = "Dark mode", not "Night mode," as we originally envisioned. This name appears to be more standard, including in our own iOS app.

Note: The ticket T218800 entertains ideas of combining Dark mode with other reading-preference features in a menu. If such a menu is implemented in the future that will be part of some as yet undefined future project. This project will focus only on dark mode, and the strong desire of engineering is to use a very simple switch or toggle.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

@alexhollender, we'd talked about doing some type of simple, toggling link for this, which would raise the issue of what the opposite of dark mode might be. Something like:

Dark mode ☾ / Default theme ☼

But of course it could be equally or more effective to use some simple widget, like a toggle switch, to select/indicate on vs. off. That would avoid the question of what to call the not-dark mode.

Initial sketch below. I'm happy to put this in Invision/freehand to allow for inline commenting if that's helpful.

@alexhollender talking to @Mooeypoo again, she has revised her opinion about whether a popup/menu or toggle switch is a good way to go. We are now back to a strong opinion that the best option here will be a simple link that switches depending on what mode you're in, like so:

☾ Dark / ☼ Default

☾ Dark / ☼ Bright

☾ Dark mode / ☼ Default theme

Accessibility is a big reason for this project, and such a toggling link will be more accessible. We can, of course, use hover text to make the link's function more clear. Something like:

  • Turn on Dark mode for low-light reading.
  • Turn Dark mode off and return to the default colors.

Also, in my opinion, just using the icon on its own does not feel quite like enough for this, even with the hover text. I understand that it is attractive from a space POV, but icons by themselves can be mysterious and it's not clear that this feature represents a well-established enough pattern for an icon to stand on its own. We could put a mockup of a version like that in front of users on the project page and see what they think, if you like. But I'd also like to see a design that at least says "Dark," with the icon. (I think I like the #2 option above, Dark/Bright.)

  • Points of reference: Twitter calls it Dark Mode, Youtube calls it Dark theme. The iOS app has "Reading theme" (all are inside preference menus).

@jmatazzoni @Mooeypoo "dark mode toggle - B.pdf" is a mockup of what we discussed in the meeting yesterday. My initial concern is that it is a new, non-standard interaction for turning a setting on/off in a very visible part of the interface. It doesn't follow the standards we as a design team are trying to champion, nor is it generally a familiar/common pattern (cc @Volker_E). I am of course happy to discuss further, and to show it to the design team to see what others think.

"dark mode toggle - C.pdf" is a more reasonable approach from an interaction standpoint, though it feels a bit awkward and unrefined to have a setting checkbox exposed directly on the screen like that, which is how I suppose I ended up with the first sketch I posted in T221809#5151828. I do think it's helpful to walk through these ideas, and appreciate the pushback in the meeting yesterday.

Also, I think accessibility is an important goal. Ideally we can find a way to make it accessible while still being compliant with our design standards.


Ooh, those look really nice, I think they work better than a popup (and as mentioned, we will have a much easier time making them accessible; the menus tend to be problematic with that)

Just a small comment from an engineering perspective here -- Both options (B and C) look great. From an engineering perspective, because of the way that the code is set-up, it will be much harder to add a checkbox up in that row for no-JS users. The top user actions menu limits the code to only be able to add links; in the case of Echo, we added a link that is then heavily customized by CSS to be replaced by an icon (and an overlay "box" of numbers) but what's actually existing in the DOM is a "raw" link.
Adding a checkbox directly in the DOM is going to be a problem. We could add it by injecting it with Javascript, but JS loads quite significantly later (a second or so) and you'd get a "jump" of the content. We can solve for that jump (css preserving space there) but it has other implications here on the product.

All of this presents a couple of questions:

  • What do we present to no-JS experience? This is important because it will dictate what the server is producing in the backend. A checkbox is not possible up there, but even if it was, a checkbox would not respond to anything without JS, so for no-JS experience it seems weird to use.
  • What is the behavior for the no-JS experience? We can do something like clicking that link reloads the page to be in the new state you asked for + set the cookie/preference. That sounds to me to be a good solution (again, no-js) but I want to make sure you two are thinking about this option.

Injecting an image/icon is easier than a checkbox (we can inject it with CSS in no-js and then "take over" the click action with Javascript) but if we're going with the checkbox,we'll need a "fallback" version for what the user sees while it loads, which ideally would be the same (or similar) to the no-js experience. So, this is about both while-loading and no-js.

One more thing, sorry for the flood here, but we might need to lazy-load the CSS styles. If we do, there might be a few milliseconds (potentially a little more to slow connections) between the user clicking the toggle and the CSS/JS being loaded and activated.

This only happens for the first time after loading the page (but for every time a new page is loaded) . So, if you loaded an article, the first time you toggle DarkMode it might take a few milliseconds to respond. If you later (without refresh or switch of articles) toggle it again it will be immediate. If you navigate to another article or reload, it will again potentially take a few milliseconds.

Please consider we might need a design for what we do during that (quick) loading time too.

Just as a note, in Echo/Notifications, we lighten the icon a bit as the JS files load and then display a loading animation. That said, Echo/Notifications are also significatntly bigger file payload, so I suspect loading dark mode will be faster. Still, it might be noticeable in slower connections, so a potential (quick) loading state is a good think to consider.

I agree option B seems best, both for non-JS users and you get that pretty moon/sun icon :)

Regarding lazy-loading, it seems our CSS won't be very big, so I would vote to have it there in the core CSS, wrapped with .darkmode. Then we just toggle that class on the <html> element. I imagine with lazy loading it will be similar to the user script, which comes out to a few hundred milliseconds load time, and that's on my fiber optic internet connection. My guess is this is mostly the round-trip to the server, and not the size of the CSS itself.

To clarify -- the lazy-loading is for whatever JS interface we come up with to toggle, not to initial style loading (it was especially important when we discussed a popup, which involves OOUI assets and is hence not that small)

The style loading should happen in the backend/PHP (for registered users, at least). We have the method of how to load that in T222470: DarkMode: Create a mechanism to activate dark mode within the extension

Whatever your choice was before, the backend will serve it to you. If your choice before was DarkMode, you'll get the CSS already, and the (tiny) js is what's going to be lazy-loaded (quickly) to change the class.

If you started with "regular" mode, then the CSS classes are *not* automatically embedded in the backend, so the toggle itself will be millisecond delayed.

There's no need to add the payload to all registered users that didn't choose DarkMode even if it's small, even if it's small. There's no real reason to, the delay is super tiny, and happens only on toggle, which is not an action that's done constantly or on a regular basis. People will enable/disable this not very frequently.

For what it’s worth, my opinion is a toggle button similar to this is the most intuitive and aesthetically pleasing option. I think “Dark” in “Dark Mode”/“Dark Theme” should correspond to “Light”, as in “Light Mode”/“Light Theme”, as opposed to “Default” or “Bright”. i.e:

☾ Dark / ☼ Light

☾ Dark Mode / ☼ Light Mode

☾ Dark Theme / ☼ Light Theme

Seeing as this will not be deployed to the WMF cluster, I think it's safe to decline this task. However any volunteer contributions in the way of design are of course welcome. For now the extension adds the link to the footer, but we plan to make this configurable (T285171).