Add and remove style variations in the Block Editor

Some of the blocks included in WP Core include style variations. They’re a nice way to have a single component that can be styled in several different ways. One example: the Button block.

As of August 2019, in version 5.2.2, Core includes 3 style variations with the Button: Default, Outline, and Squared. You can see them in two places: in the Inspector Panel (the sidebar on the right) under Styles, and if you select the block, then hit the top-left button, you’ll see the same options.

The Styles menu, showing the Default, Outline, and Squared button style variations

But what if you want to add more style variations? Or what if you don’t want the Core styles at all? No problem, there are fairly simple ways to add and remove the styles, and you don’t have to deal with Webpack or create-guten-block, just some plain uncompiled JavaScript. Since I feel that button styling fits well with a theme, the following example is how you would set up a theme to override the styles. You could instead set everything up as a plugin – the files are basically the same, you would just need a “plugin.php” file in place of “functions.php” with a few lines of comments to help WordPress recognize your code as a plugin.

Step 1: create an Editor JavaScript file

We’ll name this file “editor.js” and place it right in the root of the theme.

wp.blocks.registerBlockStyle('core/button', {
    name: 'secondary-cta',
    label: 'Secondary CTA'
});
wp.blocks.registerBlockStyle('core/button', {
    name: 'primary-cta',
    label: 'Primary CTA'
});
wp.domReady( () => {
    wp.blocks.unregisterBlockStyle('core/button', 'default');
    wp.blocks.unregisterBlockStyle('core/button', 'outline');
    wp.blocks.unregisterBlockStyle('core/button', 'squared');
});

Lines 1-8 register two new style variations for the Core Button block: Primary CTA and Secondary CTA. Lines 9-13 unregister the three Core style variations. Note: I registered my “Secondary CTA” style first because I want it to be the first, and therefore the default, option. On my sites, I use the Primary CTA very sparingly to give it more pop.

Another note: there is such a thing as a Default Style Variation. So, I tried setting up my Secondary CTA style as the default. However, I learned that once a block has a default style variation set up – as Core does, aptly named Default – you can no longer set a default style to replace the old one. So I left that setting out of the code, and just registered the one I wanted it to default to first.

Step 2: create Editor styles

Since we want the button styling to look the same in the Editor as we do on the front end, we need an editor stylesheet. Your theme might already have one, so if so (and you’re using a custom theme or a child theme), go ahead and add to that file. But many themes don’t have an editor stylesheet, so if you don’t have one, create a file called “editor.css” and place it right in the root of the theme.

// Core Button block
.wp-block-button .wp-block-button__link {
    background-color:#00f;
}
// Core Button block - Primary CTA style variation
.wp-block-button.is-style-primary-cta .wp-block-button__link {
    background-color:#f00;
}

As you can see, you need to set up one style for whatever your default is, and then for any additional style variations, you use the class “is-style-whatever-your-style-variation-is-named”. In my case, that’s “is-style-primary-cta”.

Step 3: create Front End styles

Similarly, you’ll want to set up styles for the front end. They just use slightly different classes:

// Core Button block
.wp-block-button__link {
    background-color:#00f;
}
// Core Button block - Primary CTA style variation
.is-style-primary-cta .wp-block-button__link {
    background-color:#f00;
}

You can, of course, get much fancier with your style variations. I just like to strip ideas down to their simplest form and then build up from there.

Step 3: don’t forget to enqueue everything

These files won’t actually apply until you enqueue them in your “functions.php” file (or through a plugin). Since we’re doing this work in a theme, our “style.css” file is already being enqueued, so here we’re just going to add the Editor JS and Editor CSS:

// Enqueue Block Editor styles
add_action('enqueue_block_editor_assets', 'example_editor_styles');
function example_editor_styles() {
	wp_enqueue_style('example-editor', get_template_directory_uri() . '/editor.css', array('wp-edit-blocks'));
}
// Enqueue Block Editor script
add_action('enqueue_block_editor_assets', 'example_block_enqueues');
function example_block_enqueues() {
	wp_enqueue_script('stmu-2017-block-editor', get_template_directory_uri() . '/editor.js', array('wp-edit-post', 'wp-blocks', 'wp-dom-ready'), '', true);
}

The stylesheet is pretty straightforward. You’re enqueueing it with the “enqueue_block_editor_assets” hook, which will only fire when someone loads the Block Editor, as opposed to enqueueing on the front end.

The script turned out to be a pain for me. Two things I had to get just right were:

  1. Add wp-dom-ready as a dependency. Back in our actual “editor.js” file, you can see that the calls to unregisterBlockStyle are all wrapped inside a wp.domReady condition. That makes sure that WordPress has completely loaded and has added the styles you want to remove. If the styles have not been added yet, your code will try to remove them, but then after that Core code will add them, so the end result is your code won’t remove them.
  2. Add wp-edit-post as a dependency – and add it in the right place. This one took me down a long rabbit hole of problems. Very similarly to wp.domReady, adding this dependency ensures that WordPress has added the styles you want to remove, before you try to remove them. However, the editor itself kept saying “The editor has encountered an unexpected error,” which prevented any use of the editor itself. In the console, there was a warning saying “TypeError: this.activateMode is not a function.” I learned that this error can appear for 2 separate reasons: one is if you are using lodash (because it conflicts with Core’s use of Underscore.js); and the other reason, the one that applies to this code, is because wp-edit-post and its dependency lodash has not loaded yet. So in this case, I had to add “true” to my call to wp_enqueue_script() which makes my JS load in the footer. That ensures that lodash has already loaded, so the code above can now run.

If you are only adding style variations to a block and not removing any, then you do not have to worry about either wp-edit-post or wp-dom-ready. You can simply set “wp-blocks” as the only JS dependency.

The Styles menu, showing the custom Secondary CTA and Primary CTA style variations

Leave a Reply

Your email address will not be published. Required fields are marked *