N'hésitez pas à vous abonner

Mis en ligne le
par christian

Presentation of the Palette Synchronizer

At noleam, we frequently develop sites that must follow specific brand rules and where editing should be done with respect of specific fonts, sizes and colors. On such sites, brand rules are stricts and there is no way to use an alternate color… But sometimes it is possible 🙂

Sure, it is easy to suppress customization in Gutenberg by inserting one piece of code,

add_theme_support( 'disable-custom-colors' );

but it is not so obvious in the legacy color picker (ie. TinyMCE)  or Iris based color pickers like in ACF plugin. 
But for any change in the palette elements, the developer must propagate it from CSS to several parts of JS or PHP code to synchronise all the color picker tools. This is a pain for any developer and huge source of errors (so a lack of time …)

Synchronize colors and mimic Gutenberg

The goal of the Palette Synchroniser  is to allow any developer to add color synchronisation for the different color tools employed, just with few lines of codes in one place and some specific CSS rules. So, whatever the plugins, whatever the various color pickers available, legacy, Gutenberg or Iris (like in ACF or in the customiser), the site edition team will always have the same choice of colours. 

(insert here the three samples.).

This is the default behaviour but it is possible to add some customisations. 

Another gem we add is more specific to ACF vs Gutenberg UX. ACF uses the Iris color picker but Gutenberg team developed a specific new color picker. When you mix blocks from ACF or any other block lib, you can now manage the same UX and look for Iris (ACF/Customiser) than for Gutenberg color pickers…


Implementation is done in 2 steps.

  1. Insert CSS : On CSS part, we need to declare colors in CSS variables, easy to do…
  2. Call Palette Synchroniser : On PHP part (in functions.php or any other php file you included in your code) we need to create an instance of Palette Synchroniser  with some custom settings…

And don’t worry, you do not have to declare specific has-color-… or has-backround-color-… CSS class … Palette Synchroniser scan the CSS and insert these specific CSS rules for you …

Oh wait ! Scan ?

Yes, really !! we scan the CSS file where your brand rules are defined. During development phase, or for any other purpose, each time you save a newer version of CSS, Palette Synchroniser will scan it. Then it will save the new palette information into transients so if you do not modify your brand in the future, the scan will be done from time to time (one month by default).

Screenshot of the Sabberworm repo.

To do the scan, we use Sabberworm which is a long time used and well maintained CSS parser written in PHP by Raphael Schweikert. You can find the code on github : https://github.com/sabberworm/PHP-CSS-Parser.

We’ve implemented an autoload feature that does the right class insertion and you just have to include the Sabberworm Parser class file in your code before Palette_Synchroniser class.

include_once './Sabberworm/CSS/Parser.php'; require_once './Palette-Synchroniser/Palette_Synchroniser.php';

Brand colors definition

CSS variables

Variables are really nice improvement in terms of efficiency when you build a CSS file (see W3C specifications ).

/* some colors */ --primary-color : #3B3FB6 --success-color : #28a745 /* some text fonts */ --brand-font : 'Exo', sans-serif; --fun-font: 'Bungee Shade', cursive; --icon-font: "Font Awesome 5 Duotone"; /* FA Pro only */

… and we can use var({variable}) css instruction to use the variable.

/* Headers definition */ h1 { font-family : var(--brand-font); font-size : 2rem; color : var(--primary-color); } ...

In each site I developed, I create a brand.css file that contain, colors, texts and few others definitions to be used overall. And in all others css files, then I use the variables to build the rules. But you can put all the things in a same CSS file, it works too !

In Palette Synchroniser, we have the possibility to scan such .css file in order to retrieve the colors defined for the site branding. Let say :

/** Brand colors for noleam.fr **/ root: { --color-1: #3B3FB6; --color-2: #F0B323; --color-3: #CE0037; --color-4: #9EB5CB; --color-5: #FBDD40; --color-text : var(--color-1) --white: #fff; --black: #000; --background-1: #f7cc03; }

CSS Color for Gutenberg

Here and here, Rich Tabor explains all the basics of Color classes for Gutenberg and CSS insertion. We deployed more or less the same solution, plus few enhancements. So don’t worry about Gutenberg, declare the CSS rules and enjoy !

Regarding number of colors : Although Gutenberg or Iris color pickers accept more than eight colors, it should be preferable not have max. It is a usability aspect but also a question of design.

Only #HEX on 3 or 6 digits, no alpha

We choose to declare only colors in hexa format (3 or 6 digits). Probably, a future version will check also rgb(r,g,b) colors and transform them into hexa format. As some of the targeted color pickers are not ready for managing alpha layers (and never be, I think), we’ll never accept 8 digits hexa format or rgba(r,g,b,a) declarations.


Basic usage

Here the code we need to synchronise the palette…
By default, the palette is restrictiv (no customisation) and Iris color pickers will mimic Gutenberg ones.

// Insert classes include_once './Sabberworm/CSS/Parser.php'; require_once './Palette-Synchroniser/Palette_Synchroniser.php'; // Defined Palette synchro for admin menu only if ( is_admin() ) { new Palette_Synchroniser( [ // Colors slugs used in CSS file 'color_slugs' => [ 'color-1', 'color-2', 'color-3', 'color-4', 'color-5', 'color-text', 'background-1', 'white', 'black' ], // Brand CSS file to scan (we're using a child theme) 'file' => get_stylesheet_directory() . '/assets/css/brand.css', ] ); }

See the results in Gutenberg, ACF, customiser or legacy color picker.

<onclude 3 copy>

Enqueing specific JS and CSS

Palette Synchroniser is not only a PHP file, we used two other files :

  • a Vanilla JS file to manage the synchronisation but also the Gutenberg mimic
  • a CSS file to add specific rules or to modify existing ones.

By default, both files are located in the same directory than Palette_synchroniser.php, in a plugin (plugin_dir_url( __FILE__ ) ) and enqueing as any other asset files in WordPress.

But it is possible to specify another location using the noleam/palette_synchroniser/set_url filter.

add_filter( 'noleam/palette_synchroniser/set_url', function($url) { return 'my_own_url'; } );


We wrote this class with versatility in mind and we added a lot of settings. Palette Synchroniser constructor accepts only one argument, an array of settings.

new Palette_Synchroniser( [ [ /* settings */] ] );
key usagedefault
color_slugs Array of color slugs we shall parse.
See Color palette.
No default, mandatory
filePath of the css file that contains the CSS to parse.
See CSS file.
No default, mandatory
prefixPrefix used to detects if a CSS variable is a name
for –{color-slug},
name = –{prefix}— {color-slug}
See Color names.
Default = ”
parser_pathThe location ofthe parser directory.
See Parser Location.
forceForce CSS file parsing.
See Scan period and force scan.
lifetimeCache lifetime before two CSS scan.
See Scan period and force scan.
1 month
strictWhen true, it is not possible to customize colors. Set it to false to add your users the possibility to use their own colors.
See Color customisation.
mimicIris based color pickers can mimic Gutenberg Block Picker in order ro effer similar UX.
See Gutenberg mimic mode.
legacy_modeUsed to insert the defined color palette at the beginning or append it at the end.
See Legacy mode.
syncFor each available color picker, it is possible to allow/deny the color synchronisation.
See Synchronize only some color pickers.
all to true.

Color palette


/** * Brand colors for noleam.fr * * color defined by --{color-slug} * */ root { --color-1: #3B3FB6; --color-2: #F0B323; --color-3: #CE0037; --color-4: #9EB5CB; --color-text: var(--color-1) --white: #fff; --black: #000; --background-1: #f7cc03; }


new Palette_Synchroniser( [ 'color_slugs' => [ 'color-1', 'color-2', 'color-3', 'color-4', 'color-5', 'background-1', 'white', 'black' ], // other settings ... ] );

Gutenberg color definition

Palette Synchroniser creates the required CSS for Gutenberg color usage and embed it into the code.

Using the noleam/palette-synchroniser/gutenberg_css filter, it is possible to add other css declarations and enqueuing them with the CSS generated code.

add_filter( 'noleam/palette-synchroniser/gutenberg_css', function ( $css ) { ob_start(); ?> .my-css : { color:red; } <?php $css .= preg_replace( '/\s+/', '', ob_get_clean() ); //miminize return wp_strip_all_tags( $css ); } );

CSS file

The file setting defines the path of the CSS file to scan.

new Palette_Synchroniser( [ // other settings ... 'file' => get_stylesheet_directory() . '/assets/css/brand.css', // other settings ... ] );

Color names

By defaults we use the color slug names (ie. the part after the — in css variable definition) to name the colors where it is possible to see them, like in tootips in Gutenberg color pickers. It is possible to add names by defining some new CSS variables using a specific naming rule (see example below)

/** * Brand colors for noleam.fr * * For each color defined by --{color-slug} * se defined a name --{prefix}-{color-slug} * */ --name-color-1: Dark Blue --color-1: #3B3FB6; --name-color-2: Deep Yellow --color-2: #F0B323; --name-color-3: Reddish --color-3: #CE0037; --name-color-4: Light blue --color-4: #9EB5CB; --name-color-text: Color Text --color-text: var(--color-1) --name-white: White --white: #fff; --name-black: Black --black: #000; --name-background-1: Yellow Background --background-1: #f7cc03;

On PHP side, define the right prefix to use the color names.

new Palette_Synchroniser( [ // other settings ... 'prefix' => 'name', // other settings ... ] );

<shot with tooltip>

Parser location

By default, the Sabberworm directory is located under a directory that Palette Synchroniser knows as PLUGIN_VENDOR defined variable.

define( 'NOLEAM_PATH', __DIR__ ); define( 'PLUGIN_ASSETS', NOLEAM_PATH . '/assets/' ); define( 'PLUGIN_VENDORS', PLUGIN_ASSETS . 'vendor/' );

By setting path variable, you can adjust Palette Synchroniser usage to your files configuration.

new Palette_Synchroniser( [ // other settings ... 'parser_path' => '__DIR__ . '/CSS/', // other settings ... ] );

parser_path value must be ended by a /

Scan period and force scan

You can change the scan period by setting the lifetime parameter. Default : duration = 1 month. Be careful that in a normal usage, this new setting will be taken into account only when the CSS file will be scanned once again, so at the end of the current duration.

You can force a new scan by touching the CSS file using bash or by modifying some CSS declarations, in order to create a new version. The scan will be then triggered.

new Palette_Synchroniser( [ // other settings ... 'lifetime' => 3 * MONTH_IN_SECONDS, // Every 3 months // other settings ... ] );

If you want to scan each time (#OMG) you can set it with the force parameter. Default : force = false, This could be convenient sometimes, in development phase for example.

new Palette_Synchroniser( [ // other settings ... 'force' => true, // Sure ? // other settings ... ] );

Color customisation

By default, it is not possible to customize the colors: strict = true

<include ACF without mimic strict true > <ACF with mimic>

With ‘strict’ attribut set to false, the color customisation is possible on each type of color picker.

new Palette_Synchroniser( [ // other settings ... 'strict' => false, // other settings ... ] );

<include ACF without mimic strict false > <ACF with mimic>

Gutenberg mimic mode

This is the default behaviour for the Iris based default behaviour; mimic = false

But you can force Iris normal behaviour by setting mimic to false.

new Palette_Synchroniser( [ // other settings ... 'mimic' => false, // other settings ... ] );

Legacy mode

For the legacy (ie TinyMCE) colorpicker, you can insert (by default) or append your colors to the existing palette and they will be visible in the beginning or at the end of the available colors.

new Palette_Synchroniser( [ // other settings ... 'legacy_mode' => 'append', // 'insert' by default // other settings ... ] );

You want to make some change in the palette ? You can use 2 filters .

  • noleam/palette_synchroniser/insert_legacy_palette : insert at the beginning of the palette
  • noleam/palette_synchroniser/append_legacy_palette : append at the end of the palette

Both filter have one parameter, color palette, defined as the Tiny MCE palette

add_filter( 'noleam/palette_synchroniser/insert_legacy_palette', function($palette) { // We add a new color at the first rank return array-merge([ 'fafafa', 'Another Gray' ],$palette); } );

Note that those 2 filters are fired only when strict=false (see Color customisation).

Synchronize only some color pickers

By default, blocks, ACF, Tiny MCE and Customizer color pickers are synchronised. It is possible to add some exceptions using the sync attribute. It is an array of 4 keys (blocks, acf, legacy, customizer or customiser), each representing a color picker type . Forcing one to false will deny any color customisation for the corresponding color picker (the palette used will be the default one).

new Palette_Synchroniser( [ // other settings ... 'sync' => [ 'blocks' => false, // no sync on Gutenberg 'acf' => false, ], // other settings ... ] );

The future

This tool have been developed for my own usage, so I added the functionalities I need and some others I found useful. It is intended to help developments and not to become a dedicated plugin (I do not see the interest of such plugin…). But maybe in the next future, I’ll publish a dedicated ACF field group that will help to toggle some settings. Let see…

Please feel free to share it in your projects (contact me at contact@noleam.fr for commercial projects, ie for WordPress site or plugin with some usage fees or shop).

If you find issues, have some enhancements to share, please use my github @chdenat or touch me on twitter ( @chdenat).

If you have some comments please use the comment form below.

Hope it will be useful !