WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.3k stars 4.11k forks source link

Default Colors, Theme Colors, and Custom Colors #29568

Open mtias opened 3 years ago

mtias commented 3 years ago

What is the problem?

Color handling in Gutenberg comes in two forms: colors picked from a palette and custom colors. Core provides a default color palette which can be overwritten by a theme. Colors assigned to a palette are expressed through classes. The same model applies to gradients. This is issue is not about the technical aspects of when to classes, inline styles, variables, etc, are employed but about the user expectations and theme integration.

At the moment, it’s frustrating as a user that upon switching to a theme that overwrites the default color palette you lose access to the rainbow-color set that comes with core. The core palette aims to provide quick access to distinct hues reliably. A theme palette generally aims to define a restricted set of semantic colors for branding.

The heart of the issue is the conflict that arises since colors are not always used semantically but also for individual expression. A theme might have added a color palette with just two colors — a green and a black — to define its aesthetics. Now, if a user is interacting with a pattern that contains an image with a rural landscape and the green color is picked because it matches the tone of the image, that use is not semantic in the sense the user wouldn’t expect it to change if they switch themes. Gradients are even more pronounced given there’s no sense of “primary”, “secondary”, not even distinct color names and they can be a lot more decorative (the theme Seedlet is a good example, with gradients that work more as background patterns). Assembling a gradient from scratch is also more laborious.

This distinction between semantic colors and local colors has implications for theme switching, global styles, etc. So we need to expand the handling of colors.

Another problem is tying user customization to globally used colors. Right now a custom color can only be replicated by remembering and replicating its color code. There should be an easier way to transfer a local color choice into the shared palette.

Finally we have the situation of patterns, which need to set inline colors right now to ensure they work as expected. This shouldn’t be needed if the pattern wants to use a color from the default color palette.

Proposal

Separate the core palette from the theme palette

A first step is to make the theme color palette something that works in addition to the default palette. That would allow themes to register preferred colors without necessarily overwriting the default palette. Of course, it still needs to be possible to fully disable the default palette since sites that have stricter branding guidelines might prefer to remove it entirely, the same way the custom colors interface can be disabled, but it should not be the default behaviour that a theme palette overwrites the color palette.

image

Treat theme colors semantically

The other part is treating theme colors as colors that should change upon a theme switch. This is obvious for the global styles context, where headings or link colors set to a theme color should change when switching themes. But it can also be extended to theme colors employed locally.

There is always going to be some uncertainty in determining what the intention is when applying a local color, but by having a more clearly defined “Theme” group we can set a better expectation than what is currently the case — if I apply a theme color rather than a color from the spectrum to a button block, it’s easier to expect it to change upon theme switching.

The approach of having theme colors more clearly presented in the UI, in addition to the default color-spectrum, will allow us to finally tackle a big part of the conundrum outlined in #7553. Theme colors (of the primary and secondary kind) will be expected to map to the same variables on the next theme while dark-red and light-blue are consistently provided by core but could still be tweaked within their hue range in a still predictable way (for example, we might update the default color palette with a "vibrant" or "muted" variant of the same color-coded names).

Extending the default palette

The default palette should be user customizable (as it is now in Global Styles), so a user can add, edit, or remove from it and sustain it through theme changes. That doesn't change. It's conceivable that the current colors in the default palette would need to be added, updated, or removed in the future. We should work with the assumption that we might add more default palettes in the future and that we should retain the current mappings indefinitely.

Bubble up local changes

Colors picked locally could automatically become part of the custom user palette so that the next time they want to pick the same color it's present there. A user should be able to remove a custom color at any time so that the custom palette doesn’t grow indefinitely if you use many custom colors locally. A tricky implementation detail is how to go from inline disposable color to a class-based one for this reuse, but this also helps address that problem by making it more obvious that adding a color (at least in certain contexts) automatically creates a class mapping for it.

Integration with patterns

By ensuring the default colors are present through their class mappings patterns can reliably work with them even in cases where they might not figure out in the UI for whatever reason. This is important to support a wide range of patterns and limit the need to resort to inline styles for effects.

timnicholson commented 12 months ago

I've been following this thread and have taken a look at what color naming the new TwentyTwentyFour theme is going to use and it looks to me from earlier commits that they started out with base, contrast, primary, secondary, tertiary but then started converting them over to the following. I thought we were at least standardized on primary, secondary, tertiary and then could debate background/foreground vs. base/contrast. Now we are looking at shades of base and contrast and various "accent" colors.

            "palette": [
                {
                    "color": "#f9f9f9",
                    "name": "Base",
                    "slug": "base"
                },
                {
                    "color": "#ffffff",
                    "name": "Base / Two",
                    "slug": "base-2"
                },
                {
                    "color": "#00000025",
                    "name": "Base / Three",
                    "slug": "base-3"
                },
                {
                    "color": "#111111",
                    "name": "Contrast",
                    "slug": "contrast"
                },
                {
                    "color": "#636363",
                    "name": "Contrast / Two",
                    "slug": "contrast-2"
                },
                {
                    "color": "#A4A4A4",
                    "name": "Contrast / Three",
                    "slug": "contrast-3"
                },
                {
                    "color": "#cfcabe",
                    "name": "Accent",
                    "slug": "accent"
                },
                {
                    "color": "#c2a990",
                    "name": "Accent / Two",
                    "slug": "accent-2"
                },
                {
                    "color": "#d8613c",
                    "name": "Accent / Three",
                    "slug": "accent-3"
                },
                {
                    "color": "#b1c5a4",
                    "name": "Accent / Four",
                    "slug": "accent-4"
                },
                {
                    "color": "#b5bdbc",
                    "name": "Accent / Five",
                    "slug": "accent-5"
                }
            ]

I also think that core WordPress shouldn't have used such unique color names. I assume they were purposely trying to NOT conflict with names that a theme might use. However, I think it would have been better to have more generic names to set the standards for themes to ADJUST those colors and add their own. So perhaps some basic colors, like red, orange, yellow, green, blue, and then maybe some like dark, light, and neutral.

For the FSE theme I just published, Flat Blocks, I'm using background and foreground, primary, secondary, and tertiary, but also neutral and dark as well as "alt" versions of most of those that are a darker shade of those colors.

karmatosed commented 11 months ago

@luminuu or @MaggieCabrera do you have some perspective you could give on how Twenty Twenty Four?

richtabor commented 11 months ago

The way I proposed colors for Twenty Twenty Four (https://github.com/WordPress/twentytwentyfour/pull/106) is to provide variants of base, contrast and accent. These represented as base-2, contrast-2, accent, accent-2, accent-3, etc.

Key concepts:

This affords an approach like proposed https://github.com/WordPress/gutenberg/issues/53996 for even better theme interoperability than simply matching slugs, as it wouldn't matter what the slug terms are—and colors could fallback, just like how spacing presets do. This comment explains the fallback concept well.

We're not at a point where themes can 1:1 switch and expect no color conflicts with existing content.

If your accent-4 (or quaternary) is a dark value, but your base-2 (or base-secondary) is also dark — there is nothing to catch those instances.

As Gutenberg leans in on section specific theme.json (colorways if you would) then a theme could define color/style combinations. Those would all have core-defined slugs (say colorway-1, colorway-2, etc) and colorway-2 would map to whatever your theme provided, if it provided one.

At that point color slug standardization isn't needed at all, but the fallback mechanism above would still work nicely.

justintadlock commented 11 months ago

I've been following this thread and have taken a look at what color naming the new TwentyTwentyFour theme is going to use and it looks to me from earlier commits that they started out with base, contrast, primary, secondary, tertiary but then started converting them over to the following. I thought we were at least standardized on primary, secondary, tertiary and then could debate background/foreground vs. base/contrast. Now we are looking at shades of base and contrast and various "accent" colors.

The only slugs that have become sort of standardized are base and contrast. Look at them as a best practice until a better system is implemented. More info on that here:

richtabor commented 11 months ago

The only slugs that have become sort of standardized are base and contrast.

And perhaps eventually those could be ref values, from the actual background/color values from the styles.color.background and styles.color.text top-level values.

You wouldn't need to register base/contrast in the color palette, dropping the need to standardize those as well.

MaggieCabrera commented 11 months ago

I think Rich's concept in https://github.com/WordPress/gutenberg/issues/53996 makes a lot of sense. TT4 has a wider palette range than TT2 or TT3 did and there's no consensus on how to handle that from core. I'm happy that it's helping get fire under this discussion so we finally move towards a global solution in the editor.