Block Styles in Gutenberg

Every block type in the WordPress editor can have multiple style options. Some block types already have style options like buttons and quotes.

I’ll show you how to add and remove style options from blocks.


Block styles let writers easily change the look of a block without any code. When editing a block with available styles, click the “Transform” icon in the top left to change styles.

Here are the style options available in my theme for the quote block:

This is a standard blockquote.

Citation

This is a large quote. It has a CSS class of “is-style-large”

Citation

They are technically just CSS classes added to the block. By using the Block Styles UI for previewing and selecting different styles, your clients won’t need to remember specific class names.

You can add block styles to any block type in Gutenberg: core blocks and custom blocks from plugins. See my note at the bottom on finding the block name so you can attach your custom styles to it.

Adding a script to the editor

We’ll need to create a JavaScript file in your theme or plugin and load it in the block editor. You can use the enqueue_block_editor_assets hook to load assets into the block editor. It works the same as using wp_enqueue_scripts to load assets into the frontend of the site.

Create an empty editor.js file in the directory /your-theme/assets/js/. Then add the following to your theme’s functions.php file:

/**
 * Gutenberg scripts and styles
 * @see https://www.billerickson.net/block-styles-in-gutenberg/
 */
function be_gutenberg_scripts() {

	wp_enqueue_script(
		'be-editor', 
		get_stylesheet_directory_uri() . '/assets/js/editor.js', 
		array( 'wp-blocks', 'wp-dom' ), 
		filemtime( get_stylesheet_directory() . '/assets/js/editor.js' ),
		true
	);
}
add_action( 'enqueue_block_editor_assets', 'be_gutenberg_scripts' );

Adding Block Styles

I’m working on a website with two styles of headings.

In my editor.js file I’m adding “Default” and “Alternate” style options:

wp.domReady( () => {

	wp.blocks.registerBlockStyle( 'core/heading', {
		name: 'default',
		label: 'Default',
		isDefault: true,
	} );

	wp.blocks.registerBlockStyle( 'core/heading', {
		name: 'alt',
		label: 'Alternate',
	} );

} );

When a style is selected, a class of .is-style-{name} is applied to the block. So in my stylesheet, the h2 { } has my default styling and h2.is-style-alt { } has my alternate style.

Why register a default style?

The block style selector lets you select which style you want applied, but does not let you unselect one after you’ve picked a style. If you register just one style and then select it for a block, there’s no way to unselect that block style option and return back to the default styling.

I register an extra style option called “Default” or “Regular”, but don’t add any specific styles for that style option. When a user selects the “Default” style for an h2, it uses the h2 {} styling rather than a more specific h2.is-style-default{ }.

If you add isDefault: true then this style will be marked active on blocks that don’t already have a style specified.

Removing block styles

When styling buttons in the Gutenberg block editor, I usually don’t want the style options that come standard with WordPress: rounded, square, and outline.

You can use unregisterBlockStyle to remove existing block styles from a block. Add the following to the editor.js file described above:

wp.domReady( () => {
	wp.blocks.unregisterBlockStyle( 'core/button', 'default' );
	wp.blocks.unregisterBlockStyle( 'core/button', 'outline' );
	wp.blocks.unregisterBlockStyle( 'core/button', 'squared' );
} );

I’ll often remove the defaults and then load my own button style options:

wp.domReady( () => {
	wp.blocks.unregisterBlockStyle( 'core/button', 'default' );
	wp.blocks.unregisterBlockStyle( 'core/button', 'outline' );
	wp.blocks.unregisterBlockStyle( 'core/button', 'squared' );

	wp.blocks.registerBlockStyle( 'core/button', {
		name: 'default',
		label: 'Default',
		isDefault: true,
	});

	wp.blocks.registerBlockStyle( 'core/button', {
		name: 'full-width',
		label: 'Full Width',
	} );

} );

List of block names

You need to know the full block name in order to attach or remove styles from it. Here’s a list of all the core blocks (excluding all the embed ones):

  • core/paragraph
  • core/image
  • core/heading
  • core/gallery
  • core/list
  • core/quote
  • core/audio
  • core/cover
  • core/file
  • core/video
  • core/preformatted
  • core/code
  • core/freeform
  • core/html
  • core/pullquote
  • core/table
  • core/verse
  • core/button
  • core/columns
  • core/media-text
  • core/more
  • core/nextpage
  • core/separator
  • core/spacer
  • core/shortcode
  • core/archives
  • core/categories
  • core/latest-comments
  • core/latest-posts

Finding a block’s name

A simple way to find the block name is to insert the block in a page and then print out an escaped version of post_content to see what’s stored.

I’m using ea_pp() below (code here) but you could also use print_r().

/**
 * Display Post Blocks 
 *
 */
function ea_display_post_blocks() {
	global $post;
	ea_pp( esc_html( $post->post_content ) );
}
add_action( 'wp_footer', 'ea_display_post_blocks' );

Bill Erickson

Bill Erickson is a freelance WordPress developer and a contributing developer to the Genesis framework. For the past 14 years he has worked with attorneys, publishers, corporations, and non-profits, building custom websites tailored to their needs and goals.

Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments

  1. Joy says

    You are writing about styles, and yet this page is partially unstyled. I see this page as yellow, which is my browser’s default background color. You really ought to style foreground and background together, to ensure legibility.

    • Bill Erickson says

      Interesting! I’ve been building websites for 15 years and I never knew browsers could have a non-white default background color. You learn something new everyday!

      I’ve just updated the styles on my site to add body{ background: #fff; }. Let me know if that fixes the issue for you.

  2. Shane says

    Hey! Love the articles and just finished reading your ACF + Gutenberg article which got me off the ground with blocks. What i’m stuck on is, I used render_callback() because i’m using Timber to render the template pages and it shows up nice on the front end and in the preview, but in the editor is shows up as the standard ACF Rows/List which makes it hard to use in The Block Editor, any idea on how to get my styles markup intocthe block editor? I have also enqueued my styles on the enqueue_block_assets() hook so it will use the styles for both the backend and frontend, i just can’t seem to get it working in the editor. 😞Thanks again!

    • Bill Erickson says

      It sounds like you have the mode set to ‘edit’ so it always renders like an ACF metabox in the backend. If you set it to ‘auto’ it will render like the frontend until selected, then become an editor. If you set it to ‘preview’ it will always render like the frontend and you can edit its settings in the sidebar.

      • Shane says

        Ah, thank you! Now we’re rocking. Last thing, Is it possible to edit the content of the styled blocks in the editor? As in, is it possible to edit the paragraph while seeing the style as it would be output? Trying to avoid using the tiny crammed sidebar for acf content entry. If they could edit directly in the styled block, that would be ideal.

        • Bill Erickson says

          ACF uses dynamic (PHP-driven) blocks so you don’t get the native editing experience like you do with the core blocks.

          The only way to see the content live refresh as you edit it is to use ‘preview’ mode and edit in the sidebar. For more complex blocks, you’re better off using the ‘auto’ mode and using the metabox-looking editor, then you can see the preview version when you select a different block.

  3. Shane says

    Ohhh ok, that’s why it puts it in the sidebar. I was wondering the decision behind that. Knowing that core blocks have that ability I may just take the deep dive into js for a few blocks to see how they achieve that. Thank you again, very helpful information!

Leave A Reply