How to Add Custom Block Styles to WordPress Gutenberg Blocks

A somewhat less known feature in Gutenberg is the option to set up different styles for blocks. You can register as many different styles upon any type of block in order to give the same block different designs. Possible styles for blocks are displayed as a section in the editor’s right hand side. Each style gets its own preview. If you are handling styles correctly switching between styles should immidately update the design inside the editor as well as in frontend.

WordPress’ documentation for this feature is currently not as complete and informative as it could be. So in this post we’ll take a detailed look in how you can add your custom block styles and how you should handle the styling for them.

The way this feature works is that whenever Gutenberg detects that a block type has registered as minimum one style, the “Styles” box will automatically appear in the right hand side in the editor. Inside it the editor can choose between the default style or any block style that has been added.

In earlier versions (at least before WordPress 5.3) registering a custom style required you to also register the default style (“no style”). Luckily this was fixed in the most recent versions of WordPress, So now you only need to register your custom styles, and WordPress will add the default style automatically.

You can register custom block styles in two ways; with PHP or with Javascript. We’ll take a look at both. But first some a-ha’s regarding handling your styles.

A note about enqueuing styles for Gutenberg

There might be some confusion about how and where to add your styles (CSS files); to the editor only, to frontend, or one stylesheet for both. One of the main purposes of the Gutenberg editor is making sure you can properly preview how your post content will look like, within the editor. So it’s recommended that you make sure your custom styles get applied in the editor as well as frontend.

How you handle this really depends on your project and existing stylesheet setup. If you are developing a complete theme you probably already include block styling inside your frontend stylesheet. You might consider adding a separate stylesheet that you’ll enqueue for the editor only. But this might be difficult to maintain if you add a lot of different styles. You’d have to update your styles in two places and ensure their results are the same. The solution for that would be to keep one stylesheet that you enqueue for both editor and frontend. But then your frontend would need to load at least two separate stylesheets and that might not be ideal.

Another solution is using e.g. SCSS or LESS and setting up @imports in such a way you only need to write your block styles once, and it’s applied to both editor and frontend. As you’ll see below when using PHP to register custom block styles, you have yet another option; to add inline styles. These styles will be applied in both editor and frontend. In frontend they will be added by WordPress as a custom inline <style type="text/css">...</style> inside the header.

However you choose to solve it, know that there are a couple of new hooks for register styles (and scripts) for Gutenberg. If you want to enqueue a stylesheet for both frontend and editor, use the hook enqueue_block_assets. If you want to add a stylesheet only for the editor, enqueue it inside the hook enqueue_block_editor_assets.

How to apply styling onto the custom block styles

Custom block styles will be added as a class of a certain pattern on the outermost HTML tag for the block.

The CSS class for block styles are added in the form of “is-style-<stylename>“. If you for example name your style “outline“, the block will get the class “is-style-outline“.

However you might experience that the Gutenberg editor will in some cases override your styling. I recommend prefixing your editor styling with the selector editor-styles-wrapper to ensure that your styles “win”. Keep in mind that this class doesn’t exist in frontend, so to be safe you might need to add two selectors, like so (if you are using the same stylesheet for both editor and frontend):

.is-style-colored-bottom-border, 
.editor-styles-wrapper .is-style-colored-bottom-border { 
	border-bottom: 2px solid purple;
}

Adding custom block styles with PHP

For adding a custom block type using PHP we use the function register_block_style(). The documentation is unfortunately lacking information in which hook we should use, but I have had luck with the hook init.

You need to know the Gutenberg namespaced name of your block type in order to add a custom style onto it. All standard WordPress’ blocks have the namespace “core” followed by a / and a slug version of their name. For example Gutenberg’s name for the standard paragraph block is core/paragraph.

Registering a custom block style is done in its simplest form like this:

add_action('init', function() {
	register_block_style('core/heading', [
		'name' => 'colored-bottom-border',
		'label' => __('Colored bottom border', 'txtdomain'),
	]);
});

The above code adds a custom block style onto the Heading block type, which would result in the class is-style-colored-bottom-border onto any Heading that has chosen this style.

This function provides you with two methods for adding your CSS (if you haven’t added it in some other way); either by providing inline CSS as a string, or providing a registered stylesheet handle that WordPress will enqueue for you if needed.

If you wish to add inline styling (remember, this will affect both editor and frontend), add the element ‘inline_style‘ to the function call and write out the full CSS as a string as its value:

add_action('init', function() {
	$inline_css = '.is-style-colored-bottom-border, .editor-styles-wrapper .is-style-colored-bottom-border { border-bottom: 2px solid purple; }';
	register_block_style('core/heading', [
		'name' => 'colored-bottom-border',
		'label' => __('Colored bottom border', 'txtdomain'),
		'inline_style' => $inline_css
	]);
});

If you’d rather want to make the function enqueue a stylesheet, provide its handle to the element ‘style_handle‘.

add_action('init', function() {
	wp_register_style('awp-block-styles', get_template_directory_uri() . '/assets/css/custom-block-style.css', false);
	register_block_style('core/heading', [
		'name' => 'colored-bottom-border',
		'label' => __('Colored bottom border', 'txtdomain'),
		'style_handle' => 'awp-block-styles'
	]);
});

Adjust the location of your stylesheet to fit your project. The stylesheet will be applied to both editor and frontend, but this time frontend will make a separate request to include this stylesheet. This method is not recommended if you are adding multiple block styles. Frontend will be significantly slowed down by requesting a whole bunch of separate stylesheets.

Adding custom block styles with Javascript

If you’d rather add your block styles using Javascript, this is just as easy as with PHP.

You’ll need to enqueue a Javascript file onto the editor only hook: enqueue_block_editor_assets. Your script will probably not need any dependencies, but I prefer to add at least ‘wp-blocks‘ as dependency.

add_action('enqueue_block_editor_assets', function() {
	wp_enqueue_script(
		'myguten-script', 
		get_template_directory_uri() . '/assets/js/myguten.js', 
		['wp-blocks']
	);
});

Adjust the filename and location to fit your project.

In your Javascript file you use the function registerBlockStyle() within the wp.blocks object to register custom block styles. Adding the same block style as we did in PHP above would look like:

myguten.js
wp.blocks.registerBlockStyle('core/heading', {
	name: 'colored-bottom-border',
	label: 'Colored bottom border'
});

And that’s it! Easy peasy.

Unregistering block styles

Just as you can register a block style, a block style can also be unregistered. Perhaps you want to remove some of WordPress’ default block styles? As with registering block styles you can also unregister block styles with either PHP or Javascript. But the choice between those two methods are not longer a choice of preference.

You cannot unregister a block with PHP if it was registered with Javascript, and vice versa. So you need to figure out how the style you want to remove was registered and match that with either PHP or Javascript. I believe all of WordPress’ block styles are added with Javascript (don’t quote me on this!). So if you want to remove some of those, you’ll need to go the Javascript route.

Unregistering a block style with PHP is done by calling the function unregister_block_style(), providing the block type and the style name you want to remove. For example unregistering the style added above in this post (assuming it was registered with PHP) would look like this:

add_action('init', function() {
	unregister_block_style('core/heading', 'colored-bottom-border');
});

Unregistering a block style with Javascript is done similarly with the function unregisterBlockStyle() within the wp.blocks object. However with Javascript there’s a matter of which script gets to run first, and you might encounter issues when your script is run before the registering. To solve this we use Gutenberg’s equivalent to jQuery’s “document ready” ( jQuery(document).ready(function() { ... }); ), and also add another dependency onto your script.

Let’s start by adding a new script dependency on your Javascript file enqueuing to ‘wp-edit-post‘:

add_action('enqueue_block_editor_assets', function() {
	wp_enqueue_script(
		'myguten-script', 
		get_template_directory_uri() . '/assets/js/myguten.js', 
		['wp-blocks', 'wp-edit-post']
	);
});

And inside your Javascript file, wrap your unregister function call inside wp.domReady(function() { ... }), like so:

wp.domReady(function() {
	wp.blocks.unregisterBlockStyle('core/quote', 'large');
});

As the above code shows, with Javascript we are now able to remove WordPress’ “Large” style on the Quote block. If you tried doing the same with PHP it would not work.

A side note on unregistering block styles

You might notice that even though you have successfully removed any custom block styles on a block, the “Styles” box in the editor will not go away. It stays put with only the choice “Default” inside it. If you want to completely remove the “Styles” box as to not confuse editors, you can simply unregister the default style as well (e.g. wp.blocks.unregisterBlockStyle('core/quote', 'large') ). This will fully remove the “Styles” box from the Gutenberg editor.

Leave a comment