cockpit icon indicating copy to clipboard operation
cockpit copied to clipboard

Identity customization within Cockpit itself (of colors, mainly)

Open garrett opened this issue 4 years ago • 5 comments

Discussed in https://github.com/cockpit-project/cockpit/discussions/16256

Originally posted by gabrielefronze August 24, 2021

I am on the way to customise it in order to (graphically) integrate it with an ecosystem I am working on and I would like to get some tips on how to override the default UI colours (mainly the blue/dark blue ones).


Goal: Recolor Cockpit to fit in when embedded with other applications which might not use our particular shade of blue.

Related: Distribution branding, except identity customization actually affects the look of Cockpit when logged in as well.

Somewhat related: Dark mode (#10189), as it would redefine colors as well. However, it's not necessary to implement basic identity branding tweaks. It would be bad if we had switchable dark/light modes with color overrides intended for light mode only, so custom colors should be wrapped in a @media (prefers-color-scheme: light) { } from the beginning (and extended support would include a separate block for prefers-color-scheme: dark in the future, once dark mode exists).

PatternFly has a mention of customization, but then links to the CSS variables at https://www.patternfly.org/v4/developer-resources/global-css-variables. We'd need a place to expose modifications to these variables with a linked in stylesheet that's loaded after the variables are defined.

@gabrielefronze made an attempt by modifying page.scss @ https://github.com/cockpit-project/cockpit/discussions/16256#discussioncomment-1323821, but the variables probably need to come later (as to not need all the !importants, which may cause problems if some of them are redefined locally in elements).


I think we'd need to have:

  • a file that's loaded after everything else
    • with some example customizations which are commented out
    • examples should be within a @media (prefers-color-scheme: light) { } for future-proofing
    • a link to the PF variable customization page
  • documentation (possibly by expanding the branding documentation a little)
    • to let people know that this exists
    • very light basics on how to use it

garrett avatar Sep 16 '21 09:09 garrett

Quoting myself from a proof of concept PR:


https://github.com/cockpit-project/cockpit/pull/17437#issuecomment-1150902503:

There are some issues with the basic concept:

  1. We should dynamically check if the file exists.

    • If we don't, then it'll be a 404 with anyone who does not have customizations.
    • If we ship a blank file (or one with comments) that people could customize, then customizations would be overridden on each Cockpit update.
  2. We're working on a dark mode for Cockpit.

    • When dark mode lands, it will 100% conflict with almost all customization someone would do with arbitrary custom CSS.
  3. Updates to Cockpit (and PatternFly) in general will eventually conflict with custom CSS, causing Cockpit's UI to eventually break for anyone who does customizations.

    • CSS is not an API and our CSS is not stable, as it's subject to change not just at the level of Cockpit, but also (more critically) at the level of PatternFly.
  4. Some widgets change color based on state.

    • Example: Usage bars change on warning (orange) and error (red).
  5. Arbitrarily specified colors might have color contrast issues. (Light on light and dark on dark are generally unreadable. Having red text on a green background would also be bad, for example.)


https://github.com/cockpit-project/cockpit/pull/17437#issuecomment-1150904911:

We could define some custom variables for CSS (aka: "CSS custom properties") and use those variables with fallbacks.

It would be for a custom color. However, then there's the issue with contrast. If the color is dark, then the text needs to be light, and vice versa. There's no way to detect that properly in CSS.

(If we did this, then we'd still need to dynamically detect if a custom file exists and load it if so.)


https://github.com/cockpit-project/cockpit/pull/17437#issuecomment-1150907355:

There's another problem, as well: Cockpit add-ons, like Cockpit-Podman, Cockpit-Machines, Cockpit-ostree, and all the 3rd party Cockpit add-ons like everything 45Drives develops.

These would all have to import the file or use the variables (if they exist). And it'd have to be within the scope of the page (within the iframe), as it's not communicated across the frames (document and iframe).

If it's limited to CSS variables (as mentioned above) and limited to just the shell (the stuff that isn't inside the iframe, such as the top bar and navigation), then it'd be easier. But then individual widgets couldn't be recolored and such.


Additionally, we'd probably want to use a CSS variable toggle hack, like --ON and --OFF mentioned on that page, so we could possibly say if a color is dark or light, as color contrast can be an issue with various color combinations.

garrett avatar Jun 09 '22 10:06 garrett

TODO:

  1. Implement dark mode, as anything that's specified in identity customization would most likely clash with dark mode support.
  2. Specify which parts of Cockpit would like be themed and at what priority.
  3. Come up with API via CSS Custom Properties ("CSS variables"), possibly with some "toggles" too.

Items 2 and 3 on the above list can be defined in parallel with the implementation of dark mode. Item # 2 can be suggested by anyone (so provide feedback here, please). Item # 3 would probably be drafted based on item # 2.

We would probably want to have light vs. dark mode colors for customizations too.

Ideally, there would be no CSS, as that's fragile and prone to break with Cockpit and PatternFly updates. We should stick to variables which could be handled in overrides (if they exist) and could fall back to defaults otherwise.

garrett avatar Jun 09 '22 10:06 garrett

Hey, My few cents here.

  1. In my opinion the dark-light toggle should be independent of the accent colours of a specific theme. What I mean is that, while the development of the light-dark toggle might be a good boost for implementing some kind of CSS API defining a pattern to use, the API for accent colors should be an additional layer on top of the dark-light one.
  2. on the --OFF and --ON hack I have to say it caught me off guard :) It is a bit tricky to understand, therefore we should pack it in the most verbose manner to avoid confusion in people looking at it and simply sensing the --OFF: ; as a bug!
  3. I think the best way to centralise the fallbacks is to create a top level var definition css file, intended for the "customiser" to work on. Then the file should be imported by a second css file implementing just the fallbacks. All the rest of css files should import the latter and not the directly editable file. I'll create a toy to mimic this behaviour.

gabrielefronze avatar Jun 10 '22 08:06 gabrielefronze

2. Specify which parts of Cockpit would like be themed and at what priority.

Ok, this would be my initial (and ordered) list based on what we have themed so far

  • Primary button colors
  • Link colors
  • Fonts
    • Base
    • Headings
    • Mono
  • Sidebar navigation (#view-apps?) colors: background, link background, link hover, link selected, etc
  • Top bar colors
  • Progress bar colors (background, indicator, opacity?)
  • Progress bar "danger" background color
  • Chart colors
  • Alerts colors (border-top and icon)
  • Subnav search

Thanks

dgdavid avatar Jun 17 '22 09:06 dgdavid

people looking at it and simply sensing the --OFF: ; as a bug!

That's why there's a comment in the example on the article and why we absolutely must have a comment for it too. It would be defined in :root {} something like page.scss, so it could be used by whatever CSS instead of just color customization, which would only use var(--ON) and var(--OFF).

I think the best way to centralise the fallbacks is to create a top level var definition css file, intended for the "customiser" to work on. Then the file should be imported by a second css file implementing just the fallbacks. All the rest of css files should import the latter and not the directly editable file. I'll create a toy to mimic this behaviour.

Nah, it should just be some predefined CSS variables set in the file. CSS variables cascade in the DOM and are not constrained to separate CSS files, so we don't need to act like they are.

So the editable part would only be CSS variables ("CSS custom properties"), no imports or any other CSS needed... just specific variables and their values.

garrett avatar Jun 22 '22 09:06 garrett