Make WordPress Core

Opened 3 months ago

Last modified 59 minutes ago

#49999 new enhancement

Iterating on Admin Color Schemes

Reported by: ryelle Owned by:
Milestone: 5.6 Priority: normal
Severity: normal Version:
Component: Administration Keywords: has-patch
Focuses: ui, accessibility, css Cc:


There are a set of color schemes available for wp-admin, but no new scheme has been added since these were created. If we want to add accessible color schemes (high or low contrast, dark mode, etc), we quickly run into issues with the current (Sass variable-based) system.

  1. The Sass variables are calculated from a set of about 3 colors, and those calculations only work for similar colors.

See Midnight, which sets the minimum variables and the defaults work well. Contrast the light blue color scheme, which needs to override other variables. The functions make assumptions about color & context, things that work for dark colors don't work well for light.

  1. Specificity of the core styles makes it complicated to override colors.

The default colors are defined in the main CSS, so every color scheme needs to override that. Currently this is done with a base _admin.scss file, but if a scheme needs to override a specific rule, its styles need to be just as specific. (This shouldn’t have to happen, but like above, not every color variable works out, for example the light blue color scheme also needs to override CSS)

That base file also needs to be kept up to date with any core changes.

  1. Not all colors are controlled by variables.

Text color (outside of menu & links) are not controlled by variables (not even the $text-color variable). Neither are the colors that identify actions (like unapproved comments, or deleting a post). Probably more? These would need to be overridden for high contrast & dark mode schemes.

Given those issues, how should we move forward to create new admin color schemes? If you’ve written a color scheme, are there other issues you’ve run into? Other color scheme implementations you think work well?

Attachments (1)

47682.2.diff (2.1 KB) - added by ryokuhi 3 days ago.
Second iteration to solve blue links :hover issues

Download all attachments as: .zip

Change History (23)

This ticket was mentioned in Slack in #core-css by ryelle. View the logs.

3 months ago

#2 @joyously
3 months ago

  • Component changed from General to Administration

Things to consider:

  • browser support
  • colors only? (or opacity to affect color)
  • define the main areas of an admin page and have foreground and background variables for each?
  • naming scheme for variables (back compat?)
  • type of color definition: hex, rgb, hsl
  • should the schemes enforce contrast ratio internally?

This ticket was mentioned in Slack in #core-css by ryelle. View the logs.

2 months ago

#4 @ryelle
2 months ago

I tried an approach with color schemes in Gutenberg that could be worth exploring, it uses postcss to generate a list of colors & shades. This basically just swaps out the sass magic for a custom theme function, it wouldn’t solve most of the issues above, but does modernize things a bit. It could get us out of the specificity hole, at least.

Here’s an example of how the prototype works.

Options passed into postcss:

    defaults: { primary: '#00f' },
    themes: { red: { primary: '#f00' } },

CSS file

button {
    color: theme(primary);
    background: theme(primary, shade-20);

The postcss plugin runs and generates the tints & shades by adjusting the lightness of the value as hsl & converting back to hex (prototype, doesn’t support opacity, would love for this to be smarter). The CSS it outputs looks something like this:

:root {
    --color-primary: #00f;
    --color-primary--shade-10: #00c;
    --color-primary--shade-20: #009;
    --color-primary--tint-10: #33f;
    --color-primary--tint-20: #66f;
body.admin-scheme-red {
    --color-primary: #f00;
    --color-primary--shade-10: #c00;
    --color-primary--shade-20: #900;
    --color-primary--tint-10: #f33;
    --color-primary--tint-20: #f66;
button {
    color: var(--color-primary);
    background: var(--color-primary--shade-20);

IE support is still an issue, depending on how much support we need there could be different solutions:

  • just the default fallback, no color schemes for IE
  • creating a separate CSS file with just the color values for each color scheme that's only loaded on clients that don't support custom properties (a postcss plugin could do this)

This ticket was mentioned in Slack in #accessibility by afercia. View the logs.

2 months ago

This ticket was mentioned in Slack in #core-css by kirstyburgoine. View the logs.

2 months ago

This ticket was mentioned in Slack in #core-css by ryelle. View the logs.

2 months ago

#8 @notlaura
2 months ago

A practice in design systems that use themes/color schemes is to have an additional layer of abstraction, like the current Sass variables. To expand on @ryelle's example, it would be something like this:

:root {
    --color-primary: #00f;
    --color-primary--shade-10: #00c;
    --color-primary--shade-20: #009;

body.default {
    --sidebar-color: var( --color-primary--shade-20 );

body.dark {
    --sidebar-color: var( --color-primary );

.sidebar {
    color: #00f; // See note below
    color: var( --sidebar-color );

The fallback can come from an additional PostCSS step (not sure of the specific package, but this definitely exists). For color schemes that require IE11 support (e.g. a default and those related to accessibility), PostCSS could output a different stylesheet per color scheme that contains the appropriate fallback.

We may want to think of this as an exploration of design tokens. To support themes, the design tokens can be abstract names for the colors, so in this the color primary. The token primary is assigned a color value and then applied to specific contexts, like sidebar-color. There would need to be guidelines as to how the color tokens relate to one another to ensure appropriate color contrast e.g. primary must always have a certain contrast ratio with secondary.

Here are a couple examples of this "abstract design tokens" from design systems:

This ticket was mentioned in Slack in #core-css by notlaura. View the logs.

8 weeks ago

This ticket was mentioned in Slack in #accessibility by audrasjb. View the logs.

8 weeks ago

#11 @notlaura
7 weeks ago

Copying some notes/ideas I added in @ryelle's PR to Gutenberg and discussed in the CSS chat on 5/21/2020.

A spec for registering the color schemes (we would need to consult with designers on the naming here). The workflow goal would be to have someone fill out this spec file and they have created a new color scheme:

themes: {
	blue: {
		primary: '#76765',
		secondary: '#asdhhd',
		accent: '#asdggg',
		error: '#f098asd',
		success: '#624yihfs',
		tints: {
			lightest: '99',
			lighter: '82',
			light: '72',
			dark: '30',
			darker: '21',
			darkest: '8'
		shades: {
			shallowest: '70',
			shallower: '64',
			shallow: '60',
			deep: '39',
			deeper: '25',
			deepest: '10'

PostCSS would generate custom properties for us, like these:

.theme-blue {
	--color-primary: #76765;
	--color-primary--tint-darkest: #242ads;
	--color-primary--tint-darker: #23423;
	--color-primary--tint-dark: #987972;
	// and so on...

Then there would need to be a middle, mapping step to plug the color values in to the UI based on a context - I'm not totally sure what that context would be, but perhaps a flavor of UI such as theme vs. Gutenberg vs. wp-admin, or even variations on a component:

.some-other-context {
	--button-background-color: var( --color-primary--shade-darkest );
	--button-text-color: var( --color-primary--shade-lightest );
	--button-focus-background-color: var( --color-secondary--shade-darkest );
	--button-focus-text-color: var( --color-secondary--shade-lightest );

Then the component itself would be totally separate from any specific color:

.components-button {
	background-color: var( --button-background-color );
	color: var( --button-text-color );

	// state bindings for the colors -
	// Fallbacks are perhaps in a separate stylesheet
	&:focus {
		--button-background-color: var( --button-focus-background-color );
		--button-text-color: var( --button-focus-text-color );

One requirement to this kind of approach is assuring appropriate color contrast with automated tests.

Last edited 7 weeks ago by notlaura (previous) (diff)

#12 @joyously
7 weeks ago

The problem with your middle, mapping step is that it defines Custom Properties. Oh, I see that is also in your component CSS. If you keep all the definitions at the :root level, it is much easier to be backward compatible with old browsers.
I think that's much too complicated. To reduce the number of colors used in the admin, and the chance of inaccessible combinations, I would suggest that the variables be limited to pairs (foreground, background) of colors to use for the various areas or prominence (such as primary, secondary, and hover states). There is a concern of whether the notifications should be part of the admin scheme, or always the same (specifying both foreground and background).
Generating many shades for all colors is not reducing the total colors. There are other ways of modifying a base color, such as using transparency and/or black and white semi-transparent colors in addition to the base.

This ticket was mentioned in Slack in #core-css by notlaura. View the logs.

6 weeks ago

This ticket was mentioned in Slack in #core-css by notlaura. View the logs.

4 weeks ago

#15 @Joen
10 days ago

Wonderful effort.

In https://core.trac.wordpress.org/ticket/50504 I created some work to add a new color scheme which features higher contrast (though still just AA level), and I'd love for it to land in 5.5. But I would love to also help with work on this effort to refresh and SCSS the color schemes, perhaps move towards CSS variables so we don't have to have color schemes registered in both WordPress and the block editor.

I'd love to help both with refreshing existing schemes, and creating dark and light mode themes. I could easily see a "dark mode" version of https://core.trac.wordpress.org/ticket/50504, for example, and I'd be happy to help with the block editor component of that too.

This ticket was mentioned in Slack in #design by joedolson. View the logs.

8 days ago

This ticket was mentioned in PR #386 on WordPress/wordpress-develop by youknowriad.

6 days ago

  • Keywords has-patch added

#18 @youknowriad
6 days ago

  • Milestone changed from Awaiting Review to 5.6

Hey folks, I wanted to help a bit this with these efforts. I started the PR above. It's working surprisingly well for a quick PR.

Here's some of the important notes from that PR:

  • I only added a variable for $highlight-color (and few variations for it).
  • I merged several similar colors that are close together. (I think we can probably remove/merge more by tweaking styles but this should be a separate effort).
  • I didn’t add support for CSS variables for the menu colors, I think it's better to get the system in place with a single color and decide separately to potentially add new CSS variables. The one we're certain about is the highlight color.
  • This PR requires compilation already to get the “default colors” but I'm hopeful we can remove that by just embedding the :root default colors into a CSS file that is always loaded in the admin.
  • I mirrored the naming of the Gutenberg variables like discussed in yesterday's meeting.

Also, let's consider this ticket for 5.6

3 days ago

Second iteration to solve blue links :hover issues

#19 @ryokuhi
3 days ago

Sorry, wrong ticket! If someone can remove the attached patch, feel free to do that.

This ticket was mentioned in Slack in #core-js by youknowriad. View the logs.

2 days ago

#21 @afercia
33 hours ago

Related: #50575.

This ticket was mentioned in Slack in #core-css by youknowriad. View the logs.

59 minutes ago

Note: See TracTickets for help on using tickets.