Mastering Custom Block Styles in WordPress: 6 Methods for Theme and Plugin Developers

Learn how to create custom block styles in WordPress using theme.json, PHP, or JavaScript—perfect for theme and plugin developers targeting the block editor.

Mag 7, 2025 - 19:12
 0
Mastering Custom Block Styles in WordPress: 6 Methods for Theme and Plugin Developers

Block Style Variations (block styles) enable developers to give content creators pre-made styling options for core blocks, ensuring brand consistency and streamlining content production. Using block styles can also eliminate the need to create custom blocks, reducing code maintenance.

In this guide, you’ll learn several ways to add custom block styles in WordPress, whether you’re working with a theme or a plugin. We’ll cover options using JSON (theme.json), PHP (register_block_style()), and JavaScript, with clear guidance on which method suits which situation.

You will also learn how to remove core block styles from the editor and curate the experience for your content creators. 

The theme.json code refers to block styles as “variations” (short for “block style variations”), which is sometimes confused with block variations or Global Styles variations. This post refers to these as “block styles” to avoid confusion.

This post starts with simple examples and gradually introduces more advanced methods for adding block styles, from quick theme tweaks to plugin-based approaches.

The code referenced in this post is also available on GitHub: 

You’ll want to have a basic understanding of CSS to follow along. Being comfortable with theme.json is also key, and knowing a bit about PHP and WordPress hooks will definitely come in handy.

To follow along or use the example code, you can use Studio, our free and open source local development environment, available for Mac and Windows.

  1. What are custom block styles?
  2. Method 1: add a block style via a JSON file (/styles folder) 
  3. Method 2: register block style in PHP and style it via theme.json
    1. Register block style 
    2. Add styling to theme.json
  4. Method 3: add a block style with register_block_style() (PHP)
    1. 3a. Use the style_data parameter
    2. 3b. Use the inline_style parameter
    3. 3c. Use the style_handle parameter
  5. Method 4: register block styles using JavaScript + CSS
  6. Optional: removing unwanted core block styles
  7. Summary: custom block styles at a glance
  8. Resources to learn more

What are custom block styles?

Custom block styles let you define alternative visual treatments for existing blocks, like adding a border, changing the background, or tweaking typography. 

When the block is selected, these custom styles will appear in the Styles panel within the editor sidebar, giving content creators easy ways to apply consistent, reusable design patterns. You can create as many custom block styles as you’d like.

Below you’ll find an example of the Image block. The Styles panel below shows four styles: Default, Rounded, Purple Border, and Red Border (which is the selected style showing in the editor).

A red border around an image in the WordPress editor

We’ll walk through six ways to add custom block styles in WordPress, from simple theme edits to more advanced methods.

Method 1: add a block style via a JSON file (/styles folder) 

  • Best for: Theme developers
  • Where you would typically use it: Commonly in themes 
  • Version requirements: WordPress 6.6 or higher with theme.json v3 

For theme developers, the most streamlined way to add custom block styles to a theme is to add a new file to the /styles folder. 

This method requires upgrading the theme.json schema to v3, which is only available in WordPress 6.6 and above. As a theme developer, you would either require your users to install the Gutenberg plugin or update the minimum requirement for your theme to WordPress 6.6 to ensure everything works as intended.

Say we wanted to add a blue border style called image-blue-border.json.

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 3,
	"title": "Blue Border",
	"slug": "blue-border",
	"blockTypes": [ "core/image" ],
	"styles": {
            "border": {
                    "color": "#00f9ff",
                    "style": "solid",
                    "width": "4px",
                    "radius": "15px"
                },
			"shadow": "var(--wp--preset--shadow--natural)"
		}
}

With theme.json v3, the metadata information for a block’s style is automatically registered within the WP_Block_Styles_Registry:

  • The title is the same as the label from the register_block_style code.
  • The slug is similar to the name property of the register_block_style function.
  • The blockTypes property can be used to assign a style to a particular block or series of blocks.
a blue border around the image block in the WordPress editor

The code "shadow": "var(--wp--preset--shadow--natural)" refers to the preset “Natural” shadow style in WordPress. By using a preset variable, your block will automatically reflect any global style changes, keeping your design consistent across themes and updates.

Once you save your code changes:

  • Your new style is added to the Styles panel for that particular block. 
  • The block editor shows a preview when you hover over the button.
  • The Styles engine attaches the CSS class is-blue-border to the block in the editor and on the frontend.
  • When opening the Global Styles via Styles → Blocks → Image, the styles can be changed by the user for the whole site. 

To organize your block style code, you can create a subfolder in the styles folder called /blocks and keep them all together. A few theme developers found they could reduce the length of their functions.php file considerably by implementing subfolders instead.

Method 2: register block style in PHP and style it via theme.json

  • Best for: Theme developers
  • Where you would typically use it: In the theme.json file and in functions.php
  • Version requirements: WordPress 6.6 or higher with theme.json v3 

To add a custom block style using this method, you’ll need to register the style and add your stylings in the theme.json file.

Register block style 

In your functions.php file, use the register_block_style() function to set the two mandatory arguments (additional optional arguments are covered below): 

  • name: The identifier of the style used to compute a CSS class.
  • label: A human-readable label for the style.

Once set, you can add them to the init hook in your theme. 

function my_style_red(){

   register_block_style(
       'core/image',
       array(
           'name'  => 'red-border',
           'label' => __( 'Red Border', 'my-theme' )
       )
   );
}
add_action( 'init', 'my_style_red' );

Add styling to theme.json

We’ll add some styling for the red-border variation to the theme.json file. It’s placed within the styles.blocks.core/image section, as we’re making changes to the Image block.

"styles": {
       "blocks": {
           "core/image":{
               "variations": {
                   "red-border":{
                       "border": {
                               "color":"#cf2e2e",
                               "style": "solid",
                               "width": "4px",
                               "radius":"15px"
                       }
                   }
               }
           },

These two code snippets work together because the name used in the register_block_style() function in your functions.php file and the variations’ name arguments in your theme.json file are identical. 

This method produces the same editor and frontend results as using a JSON file in the /styles folder:

  • The style will be visible in the editor and on the frontend. 
  • It is also available via the Editor → Styles → Blocks → Image section for global customization.
a red border around an image block in the Global Styles in WordPress

If the styles available in theme.json aren’t enough, you have a few options: 

  • You can use the CSS property in JSON notation. The WordPress.org per-block CSS with theme.json article provides a good summary of how to do this. 
  • You can use any of the methods below and add them to your functions.php file. 
  • You can register the block style via register_block_style() and include the CSS in your theme’s overall style.css file, referencing the block and style class name. That being said, this is not recommended as these styles will always load, even if the block isn’t in use. A bug is also preventing the styles from loading on the frontend.
  • You can use block stylesheets to only load the styles when the block is used, as outlined in the WordPress Theme handbook tutorial on block stylesheets

Method 3: add a block style with register_block_style() (PHP)

The register_block_style() function has three additional and optional parameters. They are listed on the documentation page for the WP_Block_Styles_Registry class that handles the registration and management of block styles.

  • style_data: A theme.json-like object used to generate CSS.
  • inline_style: Inline CSS code that registers the CSS class required for the style.
  • style_handle: The handle of a previously registered style to enqueue alongside the block style.

See the documentation for register_block_style() for more information.

3a. Use the style_data parameter

  • Best for: Plugin developers and theme developers
  • Where you would typically use it: In plugin files or functions.php 
  • Version requirements: WordPress 6.6 or higher

Although block styles have been a fundamental way that WordPress works since 5.0, the style_data parameter was added in WordPress 6.6. 

This method for defining block styles uses “a theme.json-like object,” meaning an array of nested styles in a format that very closely resembles the styles section of the theme.json file. At the root level, the styles are applied to the block(s) that you define with the block_name array. 

If you are familiar with theme.json structure, you can use this method to add additional styles. This method enables those styles in Editor → Styles → Blocks and users can make changes there. 

As you can see, the array notation for this parameter follows JSON closely. 

The theme.json reads:

"border": {
             "color":"#cf2e2e",
             "style": "solid",
             "width": "4px",
             "radius":"15px"
          }

The array in PHP reads:

array(
       'border' => array(
       'color' => '#f5bc42',
       'style' => 'solid',
       'width' => '4px',
       'radius' => '15px'
      ),

To further demonstrate this idea, this function adds an orange border with a box shadow using the “sharp” shadow style preset. 

function my_orange_border() {

   register_block_style(
       array( 'core/image' ),
       array(
           'name'         => 'orange-border',
           'label'        => __( 'Orange Border', 'pauli' ),
           'style_data'=> array(
                           'border' => array(
                           'color' => '#f5bc42',
                            'style' => 'solid',
                            'width' => '4px',
                            'radius' => '15px'
                           ),
                       'shadow' => array(
                           'var(--wp--preset--shadow--sharp)'
                           )
                       )

           )
   );
};

add_action( 'init', 'my_orange_border' );
An Orange Border style selected in the Styles panel and the orange border showing on the image in the WordPress editor

Of the three parameters, only the style_data information will be added to the global style section in the site editor and can be edited by the site owner. The other two add the styles to the Styles panel, and there is no edit path within the UI.

3b. Use the inline_style parameter

  • Best for: Plugin developers and theme developers
  • Where you would typically use it: In the main plugin PHP file or functions.php
  • Version requirements: WordPress 5 or higher

The value for the inline_style parameter is a combination of the CSS selector and the CSS properties.

function my_double_frame_styles() {
   register_block_style(
       'core/image',
       array(
           'name'         => 'double-frame',
           'label'        => __( 'Double-Frame', 'pauli' ),
           'inline_style' => '.wp-block-image.is-style-double-frame
                               img { border: 10px ridge lightgreen; }'
       )
   );
}
add_action( 'init', 'my_double_frame_styles' );
A Double Frame style selected in the Styles panel and the green border showing on the image in the WordPress editor

The class name follows standard block editor naming conventions. Each core block’s class name contains the prefix wp-block + the block name, like image. It is then followed by the block style prefix is-style and the registered style slug, like double-frame.

The class name .wp-block-image.is-style-double-frame is followed by the style that you want to attach to the block. Here you see the CSS values for the border property for the image element (img). It adds a ridged, light green 1px border. 

You can have quite a few CSS properties combined in the inline_style parameter for the function, but it may become hard to read and manage.

3c. Use the style_handle parameter

  • Best for: Plugin developers and theme developers
  • Where you would typically use it: In plugin files or functions.php
  • Version requirements: WordPress 5 or higher

For more elaborate styles, consider placing the CSS in a separate file and using wp_enqueue_style() to load it on the frontend and backend. Then use the style_handle parameter in the register_block_style() function. 

Here is some example code using this method to add a purple border style.

function my_purple_border_styles() {
   wp_enqueue_style(
       'my-image-block-style',
       plugin_dir_url(__FILE__) . '/my-purple-border.css',
       array( 'wp-edit-blocks' ),
       '1.0'
   );
 
   register_block_style(
       'core/image',
       array(
           'name'         => 'purple-border',
           'label'        => __( 'Purple Border, slightly rounded', 'pauli' ),
           'style_handle' => 'my-image-block-style'
       )
   );
}

And here is the accompanying my-purple-border.css file, which is placed into the plugin’s root folder.

.is-style-purple-border img {
   border: 6px solid purple;
   border-radius: 15px;
   box-shadow: 10px 5px 5px #e090fc;
};

The image block now has a purple border with a pinkish shadow style. 

A purple border style selected in the Styles panel and the purple border showing on the image in the WordPress editor

Note: There is also a bug report open about the stylesheet loading even when the block styles aren’t used. Because of this, it’s not recommended for complex CSS.

Method 4: register block styles using JavaScript + CSS

  • Best for: Plugin developers and theme developers
  • Where you would typically use it: In a separate *.js file, enqueued in a plugin file, or in functions.php
  • Version requirements: WordPress 5 or higher

Compared to using the separate JSON file to add a block style variation, using JavaScript is more elaborate. It has three parts: 

  • PHP: To enqueue the necessary files
  • JavaScript: To register the block style
  • CSS: To style the block

The wp_enqueue_script() function adds JavaScript files to a webpage. It’s not JavaScript itself, but rather a WordPress PHP function that’s often used in WordPress theme or plugin development. For this example, we can store the .js file in the theme’s /js/ subdirectory and name it curate-core.js

The example code loads our custom curate-core.js file after the necessary WordPress block editor scripts. It’s added to the bottom of the page for better performance and is hooked into enqueue_block_editor_assets so it only loads in the editor. 

This code example goes into the theme’s functions.php file or your plugin’s *.php file. 

function pauli_block_editor_scripts() {
       wp_enqueue_script(
           'pauli-editor',
           get_theme_file_uri( '/js/curate-core.js' ),
           array( 'wp-blocks', 'wp-dom' ),
           wp_get_theme()->get( 'Version' ), true
       );
       }
      
add_action( 'enqueue_block_editor_assets', 'pauli_block_editor_scripts' );

This code should go in the JavaScript file curate-core.js:

wp.domReady( function() {
   
   wp.blocks.registerBlockStyle(
       'core/image', {
           name: 'black-border',
           label: 'Black Border',
       }
   );

} );

You can then add our block styles to your theme’s style.css file using the automatically added class name, is-style-black-border.

.is-style-black-border img {
   border: 15px ridge black;
}

Due to a bug, you need to add the style.css to the frontend. It doesn’t seem to be automatically loaded. You use wp_enqueue_style() and then use the hook wp_enqueue_scripts.

Then you’d add the following to your functions.php or plugin file:

function enqueue_theme_styles() {
   wp_enqueue_style(
       'my-theme-styles',
       get_stylesheet_uri(), // This gets your style.css
       array(),
       wp_get_theme()->get( 'Version' )
   );
}
add_action( 'wp_enqueue_scripts', 'enqueue_theme_styles' );

You also need to add style.css to the block editor so your users can see how the block style looks when they are working on the post or page. 

//add style.css to editor
function add_theme_editor_styles() {
   add_editor_style( 'style.css' );
}
add_action( 'after_setup_theme', 'add_theme_editor_styles' );
A black border style selected in the Styles panel and the black border showing on the image in the WordPress editor

Optional: removing unwanted core block styles

Now that you know how to add block styles to your theme or your plugin, you might also want to remove some additional block styles that come with the block editor out of the box.

There are two functions you’ll need to address: 

Block styles can only be unregistered in the same coding language used to register them. All core blocks are registered with JavaScript. 

The example code below removes the additional block style for the image block called rounded.

wp.domReady( function() {
   wp.blocks.unregisterBlockStyle( 'core/image', [ 'rounded' ] );
} );

For more ways to modify the block editor, read 15 ways to curate the WordPress editing experience.

Summary: custom block styles at a glance

You now know the six ways to register block styles for the WordPress block editor. Here’s a quick recap of what we covered:

Block Style Added in Example CodeLanguageTheme/PluginParameterFileGlobal Styles
                        </div>
                                            <div class= Leggi Di Più

Questo sito utilizza i cookie. Continuando a navigare nel sito, accetti il nostro utilizzo dei cookie.