Block themes for classic theme developers – part three

Ok, so I covered the templates, template parts, patterns, theme.json, and global styles in the last two articles. In this article, I will go through some additional functionalities which may come in handy in creating a Block theme.

But I do suggest (if you are new to Block themes) to read my first two articles where I was getting familiar with Full Site Editing (Site editor) and Block theme creation concepts and tried to pass on the knowledge acquired.

Enqueue block style

In part one of the Block themes… article series I mentioned the wp_enqueue_block_style() PHP function. This function enables theme developers to start going beyond theme.json and template editor – create custom styling for blocks.

In our starter theme, there are a couple of blocks utilizing this feature. In the functions.php file, there’s an array of blocks inside the function hooked to after_setup_theme hook, in the functions.php file:

function micemade_fse_store_setup() {
    // ... 
    $styled_blocks = [ 'button', 'file', 'latest-comments', 'latest-posts', 'quote', 'search' ];
    foreach ( $styled_blocks as $block_name ) {
        $args = array(
            'handle' => "micemade-fse-store-$block_name",
            'src'    => get_theme_file_uri( "assets/css/blocks/$block_name.min.css" ),
            'path'   => get_theme_file_path( "assets/css/blocks/$block_name.min.css" ),
        // Replace the "core" prefix if you are styling blocks from plugins.
        wp_enqueue_block_style( "core/$block_name", $args );
add_action( 'after_setup_theme', 'micemade_fse_store_setup' );

Using the foreach loop, blocks from the array CSS styles are being enqueued from the “assets/css/blocks” directory. The example of button.css from that directory is using presets and custom style CSS variables created in theme.json:

.wp-block-button__link {
    box-shadow: var(--wp--custom--small-button-shadow);

.wp-block-button__link:hover {
    color: var(--wp--preset--color--foreground);
    filter: var(--wp-custom--button-filter);
    box-shadow: var(--wp--custom--small-button-shadow);
... and so on ...

I would recommend using presets and custom CSS variables defined in the theme.json, as this will add consistency in design, and enable style control from one place (theme.json). It can also help style variations more powerful. (I changed an original “static” filter value to a CSS variable, and added a settings.custom.button-filter property to theme.json)

Register block style

The register_block_style() is going to expand your theme customization options in a similar way as style variations (Global styles), only it will create styles per block level.

In the example for the button, the starter theme has two block styles added to a default “Fill” and “Outline” styles – “Flat button” and “With shadow”:

function micemade_fse_store_register_block_styles() {
            'name'  => 'micemade-fse-store-flat-button',
            'label' => __( 'Flat button', 'micemade-fse-store' ),

            'name'  => 'micemade-fse-store-button-shadow',
            'label' => __( 'With shadow', 'micemade-fse-store' ),
add_action( 'init', 'micemade_fse_store_register_block_styles' );

Style properties are defined in enqueued style (in this case, the registered-block-styles.css in “assets/css” directory).
CSS selector is-style-{name of registered block style} will be added to a button block, when selected. Example of “Button with shadow“registered style:

.is-style-micemade-fse-store-button-shadow .wp-block-button__link {
    box-shadow: var(--wp--custom--button-shadow);

The button shadow is defined with settings.custom.button-shadow in the theme.json.

Of course, you can add as many block styles, to any number of blocks, it all depends on how many customization options would you like to offer to theme users.

Unregister block style

If for some reason, you would like to unregister core block styles, you can! But this time, some JS coding will be needed.

To unregister, use WordPress’ hook 'enqueue_block_editor_assets‘ and load unregister.js from “assets/js”directory :


function micemade_fse_store_unregister_block_style() {
        get_stylesheet_directory_uri() . '/assets/js/unregister.js',
        array( 'wp-blocks', 'wp-dom-ready', 'wp-edit-post' ),
add_action( 'enqueue_block_editor_assets', 'micemade_fse_store_unregister_block_style' );


wp.domReady(() => {
    wp.blocks.unregisterBlockStyle('core/quote', 'large');
    wp.blocks.unregisterBlockStyle('core/quote', 'plain');

On domReady() event, hooked to wp global JS object the unregisterBlockStyle method will unregister default styles for the Quote block.

This is just one example, more about registering/unregistering block styles you can learn from here – Block Editor Handbook/ Styles 🔗

There is also a unregister_block_style() PHP function, but it won’t work unless the block style is registered server side. The function does not unregister a style registered using client-side code.

Register block variations

Similar to unregistering block style, register block variations will need enqueuing a custom JS file using a hook ‘enqueue_block_editor_assets‘. With the block variations, users can add a customized version of a block, with predefined properties, from the inserter.

Although it may seem block variations are the same thing as block styles, block variations can be used to pre-fill custom attributes (including custom classes) and inner blocks. The block styles are registering style in options sidebar, and add CSS selector to block, which is defined in theme enqueued stylesheet.

In our starter theme, there is a block variation added to a group block, with an attribute align:full. When a user uses an inserter, or types /full in blank (paragraph) block, the “Full width group” will be offered as an option. When selected, the Group block will be added to the layout, with the preselected “full width” option.


function micemade_fse_store_register_block_variation() {
		get_template_directory_uri() . '/assets/js/block-variation.js',
		array( 'wp-blocks' ),
add_action( 'enqueue_block_editor_assets', 'micemade_fse_store_register_block_variation' );


wp.blocks.registerBlockVariation('core/group', {
	name: 'full-width-group',
	title: 'Full width group',
	attributes: {
		align: 'full',

Additional Resources:

Closing words …

And, there you go … By now, you should, as I did, have a grasp on how a Block theme works as a concept and how to catch up with the future theme building (no pun intended). These are the basics, and how will you build upon them, it’s of course, entirely up to you.

Writing this series of articles really helped me to learn Full Site Editing with a Block theme. Thinking about how to structure and articulate the information for better reading and understanding (for readers, as well as future-me) made my learning of creating Block themes much more efficient and in-depth. That is one reason for these articles.

Another reason is to share what I’ve learned and contribute to better adoption of this new WP paradigm, especially for people like me (classic theme devs), and the WP community in general. A reminder to check the first two articles:

Let’s face it – blocks, block themes, site editor, and full site editing are here to stay. It’s the future of WordPress, with all its benefits, and some downsides, too.

You, same as me, might have concluded already: that the experience and knowledge needed for creating Block themes are somewhere between the developer and designer/editor’s areas of expertise. It certainly is a shift away from the ways how I’m used to developing in WordPress, and when accustomed to new tooling and workflow, it might make the process of creating themes faster. That is if you’re going to stay in the realm of simpler, WordPress Block themes.

%d bloggers like this: