Cockpit: dark mode

Created on 1 Oct 2018  Â·  12Comments  Â·  Source: cockpit-project/cockpit

A lot of apps are adding dark mode these days. I wondered if there would be an easy way to do this via CSS filters.

This morning, I tested a simple proof of concept by adding:

.area-ct-content {
   filter: hue-rotate(180deg) invert(150%) brightness(1.5);
}

And it's nearly perfect.

(Before using the brightness boost, I did a text-shadow: 0 0; to make the light colored fonts render better on a dark background. The brightness boost is probably better, as it also makes subtle colors like light lines and the hover color a little more noticeable.)

In order to properly implement it, we'd probably want:

  1. a user preference (most likely stored in a cookie, so it's really per-browser)
  2. handle background screens behind dialogs (invert the color to be lighter instead of darker, so it shows up darker when inverted — it's basically one more line of CSS)
  3. adjust the navigation UI (make it a little more contrasty / darker — but it's actually not bad as-is)
  4. prevent the flash of white when switching between pages (probably by splitting out the inversion & hue-rotate into something more top-level, then re-inverting the navigation UI and apply the brightness boost to the content in its own filter)
  5. have an auto setting for time & date switching?

Similarly, we can have a high contrast or low contrast accessibility mode done in a very similar manner.

The biggest drawback is that we do not have precedent to have settings stored outside the system itself. (And try to avoid that.) As this would only affect the browser, having a cookie setting would probably still make sense despite that?

enhancement

Most helpful comment

Mobile

(I scaled this down so it wouldn't be super-huge as a preview here.)

screen shot 2018-10-01 at 10 46 25

All 12 comments

I can't tease a dark mode without screenshots. So here are some screenshots. Remember, this is the _only 1 line of CSS_ proof-of-concept.

System overview

screenshot_2018-10-01 system - sunny

Storage page

screenshot_2018-10-01 storage - sunny

Dialog on the storage page

(Here's where the fix for item 2 would be needed.)
screenshot_2018-10-01 storage - sunny 1

Mobile

(I scaled this down so it wouldn't be super-huge as a preview here.)

screen shot 2018-10-01 at 10 46 25

Very Nice!

See also https://stackoverflow.com/a/51799496/176160 It is likely there will soon be some support for determining if the browser is running in dark mode.

Firefox 67 landed this week and now includes dark mode support.

  • On OSes that have a toggle, it supports the toggle.
  • On Linux, it checks the GTK foreground and background colors and infers a theme
  • On all OSes, there are overrides

OS-based dark mode in browsers (prefers-color-scheme) is only supported in Firefox and Safari. Chrome support is forthcoming (and should land some time this year).

I'm currently working on overhauling all our colors in issue https://github.com/cockpit-project/cockpit/issues/11913.

Once done, this should allow us to support dark mode in a cleaner and more performant way, by redefining all the colors. (That said, I didn't notice performance issues. But it probably would have at least a little impact to flip the colors around.)

The method used above could be useful for parts of Cockpit that might not be easy to re-theme (such as the graphs), other top-level add-ons (such as Composer) or remote machines running old versions of Cockpit. The latter two exapmples would probably need additional work — perhaps by adding a special class in an iframe to enable color-variable-based dark mode and then defaulting to the above inversion method otherwise (if the class does not exist). We'd want to make sure there isn't a jarring white background in dark mode, in other words, and would need to mix-and-match techniques to get it done.

The color reworking was absorbed in to an overall restyling of Cockpit in https://github.com/cockpit-project/cockpit/pull/11987.

Not all the colors have been ported over to variables, but most have.

Adding a proper dark mode would help spot other colors that have not been adjusted.

Meanwhile, here's a great article on the whens, whys, & hows of dark mode:
https://web.dev/prefers-color-scheme/

Coded a flexible and working solution for the Dark Mode.

Demo in here:
https://dorson.github.io/CSS-Dark-Mode-and-color-switch/

Works with basic CSS variables + short JavaScript.

Can be used to define multiple color themes in one CSS file or other dynamic style setting options like text size, etc...

Have fun using my code !

@Dorson: Thanks for the link. However, Cockpit is pretty complex, being a mix of PF3, PF4, and a lot of custom code. We'd have to have our own implementation of dark mode. PF4 already has some preliminary dark widget support, but that would only get us so far. Whatever is made for Cockpit would have to handle everything. We'd probably have to use more than one technique. (Like an optimized path when possible and possibly even a fallback one that is slightly less performant for legacy code and third-party extensions that don't directly support a dark mode.)

Plus, there are various design considerations to take in mind when developing a dark mode (more than inverting + shifting hue), as mentioned in the link I just shared above.

Glad you know that you're interested in dark mode though! The higher the want for it, the more likely we can get to it sooner than later (if at all).

Copy/pasted from https://github.com/martinpitt/performance-graphs/pull/64#issuecomment-702187607:


Ideally, PatternFly would have a class for dark mode. IIRC, they would enable it at the top of the page _or_ at a specific widget level.

So we could do something like this in SCSS:

.foo {
   color: var(--some-color);
  .dark-mode & {
     --some-color: #fff;
     background: red;
  }
}

And SASS would unwrap that as:

.foo { ... }
.dark-mode .foo { ... }

And the specificity of the dark mode overrides would win out. It would also be afterward too. :wink:

FWIW: PF would probably go with .pf-m-darkmode or something such.


Also: If dark mode is applied to the same widget, then we'd do this instead:

.foo {
   &.dark-mode {}
}

But, in most cases, we'd want dark mode at the top of the page and have everything inherit.

Ideally, we'd try to use PF4's dark mode (with it lands) and have a fallback for non-PF with the example I outlined above (in which we'd probably also drop or adjust the dropshadows so they're not "dropglows").

And we'd have a little bit of CSS like the above comment for one-off overrides where necessary.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FireDrunk picture FireDrunk  Â·  6Comments

andreasn picture andreasn  Â·  6Comments

kai4785 picture kai4785  Â·  4Comments

851d229 picture 851d229  Â·  6Comments

cedroid09 picture cedroid09  Â·  5Comments