Colorless wp-admin?


Sometimes you get an idea in your head and you just need to follow through. With all the talk about revisiting wp-admin color schemes, I wondered… could I remove all the colors from all the stylesheets? What would that look like?

I already had a tool parsing out stylesheets to count colors, so I went to repurpose that. I ended up creating a postcss plugin that, when run on a CSS file, removes any declaration with a color value. The exception to this are border* & outline, which are split up into their longhand values first, to try to preserve as much structure as possible.

The end result:

The WordPress Dashboard, using browser default colors.
The WordPress Dashboard, using browser default colors.

Everything has a transparent background, showing the white browser background. The text is all black, except for blue & purple links. Widgets still have their outlines, so it ends up looking more like a high-def wireframe than a real website.

Again, everything’s using browser defaults. You can see what’s meant to be the current menu item ◀ is just a big black square, since it uses mix of transparent + color borders to create that effect. The plugin modal is almost okay— it’s an iframe, so it gets a default-white background, and the modal script injects the black overlay. This view really showed me how much color plays into how I scan a notice. Regardless, it holds up surprisingly well.

But when we try to open the media library, things are wonky. With no background color, the Attachment Details modal is unusable. So maybe a reset by way of removing all colors isn’t a great idea, sometimes the colors are “structural”.

Admin bar on the front end of the site

I almost like this transparent admin bar. It’s inheriting the theme styles, which is why the links are black here. The lack of background color does make it hard to read, though.


If you want to try this out on your own CSS, here’s the plugin I wrote. You can run it directly by adding it to postcss.config.js like so, then running postcss however you usually do (I used postcss-cli for this).

// postcss.config.js
module.exports = {
	plugins: [
		require( './remove-colors.js' )(),
	],
};

Download remove-colors.js directly

const postcss = require( 'postcss' );
const getColors = require( 'get-css-colors' );
/* A size is any number, optionally with a unit. */
const isSize = ( value ) => /^\d+\s?([a-zA-Z]+)?$/.test( value.trim() );
/* If the value has a color in it, getColors will return an array. */
const isColor = ( value ) => null !== getColors( value );
/* A line style is from a set of values */
const isLineStyle = ( value ) =>
-1 !==
[
'auto', // Technically only allowed on outline.
'none',
'hidden',
'dotted',
'dashed',
'solid',
'double',
'groove',
'ridge',
'inset',
'outset',
].indexOf( value );
function explodeProp( decl ) {
switch ( decl.prop ) {
case 'border':
case 'border-top':
case 'border-right':
case 'border-bottom':
case 'border-left':
case 'outline':
const values = decl.value.split( ' ' );
values.forEach( ( value ) => {
if ( isLineStyle( value ) ) {
decl.before(
postcss.decl( { prop: decl.prop + '-style', value } )
);
} else if (
isSize( value ) ||
-1 !== [ 'thin', 'medium', 'thick' ].indexOf( value )
) {
decl.before(
postcss.decl( { prop: decl.prop + '-width', value } )
);
} else if ( isColor( value ) ) {
decl.before(
postcss.decl( { prop: decl.prop + '-color', value } )
);
}
} );
decl.remove();
break;
}
}
module.exports = postcss.plugin( 'remove-colors', function() {
return function( root ) {
root.walkRules( ( rule ) => {
// Explode out the border/outline props.
rule.walkDecls( ( decl ) => {
explodeProp( decl );
} );
// Remove any declarations that have color.
rule.walkDecls( ( decl ) => {
const hasColors = getColors( decl.value );
// grayscale isn't actually a color, it's used in antialiasing.
if ( 'grayscale' === decl.value ) {
return;
}
if ( Array.isArray( hasColors ) ) {
let value = decl.value.slice();
hasColors.forEach( ( color ) => {
value = value.replace( color, '' );
} );
decl.remove();
}
} );
} );
// Remove all empty rule blocks.
root.walkRules( ( rule ) => {
if ( rule.nodes && 0 === rule.nodes.length ) {
rule.remove();
}
} );
// Remove all empty @rule blocks.
root.walkAtRules( ( rule ) => {
if ( rule.nodes && 0 === rule.nodes.length ) {
rule.remove();
}
} );
};
} );

Posted in:

Previous:
Next:

Comments

No comments.