WordPress offers many ways to style blocks. In this lesson I want to talk about registering block style variations and section styles that helps users select premade designs.
The custom block styles, often called block style variations, are options in the Styles section of the block settings sidebar. You use them to quickly apply styles without having to adjust individual settings. Common examples of block styles are the filled and outlined buttons and the rounded image:

Block styles can help users overcome decision fatigue. They can inspire users by offering different premade design, and help us work faster by avoiding repetitive tasks.
What is the difference between block styles, section styles, and patterns?
Block styles in this context are style variations for one or more blocks. To use the style, you insert the block and then select the style option in the block’s settings sidebar.
Section styles is exactly the same thing, except the styles are also applied to nested blocks and elements.
For example, if you have a group block with a heading, image and paragraph, you can use a single block style to only style the heading, or you can use a section style to style all the blocks.
Block styles are options that adds styling to existing blocks, compared to patterns that insert new blocks into your content or template, with or without styling. You can combine patterns and section styles. That way, users can insert patterns and then quickly change the colors, spacing and typography.
How do custom block styles work?
When you create your block style you can choose between adding custom CSS, using a theme.json style variation, or registering an array of style data using PHP. The two latter options are available from WordPress 6.6, and I describe each option below.
Block styles work by generating and adding a CSS class to the block and applying the styles to the new selector. When you have selected a block style in the editor, you can open the Advanced section of the block settings sidebar and see that WordPress adds the class in the Additional CSS class(es) field. WordPress automatically loads the CSS in the editors and the front (unless you choose to register your style using a stylesheet -then you must enqueue it yourself).
It is important to know that these block styles are only an extra layer of CSS on top of the block’s default style. It does not remove the default style, it overrides it using a higher CSS specificity.
Example: If you register and select a style that adds a background color to a block, then it will not be reflected in the block’s background color control.
If you decide to use the background color control to add a new color, this setting will override both the default block style and the style variation.
You are not limited to styling blocks from WordPress core. If you know the prefix and the slug, you can also style blocks from plugins.
How to register custom block styles
You can register the custom block style with PHP, JavaScript or JSON (from WP 6.6). Which method you choose depends on personal preference and how you wish to organize your theme files.
Registering block styles using JSON
To register a style with JSON, you need to have basic knowledge about theme.json. You will need to create a new JSON file with the same formatting as theme.json, but with some modifications. You will need one file per style, and you need to place it in the themes styles
folder, or in a subfolder of styles.
If you need a refresher about theme.json, check out this list of lessons.
This feature is available from WordPress 6.6, so in the code examples I have made sure to use version 3 of theme.json. Because this feature is new, you may find that settings like color and typography work, but that more advanced features like block gap are still being worked on.
New features will be added to the Gutenberg plugin first, and are planned to be included in WordPress core later this year in WordPress 6.7.
The key and value pairs that are unique for the block style variations are:
- slug: The unique identifier that WordPress uses to create the CSS class.
- blockTypes: The list of blocks that you want to apply the style to.
The title is the the visible label in the editor. Note that long titles are truncated and may not show in the interface.
In this code example I am styling a group by setting the border radius, colors and padding:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"title": "Light background",
"slug": "section-1",
"blockTypes": [ "core/group" ],
"styles": {
"border": {
"radius": "4px"
},
"color": {
"background": "#FFF",
"text": "#111"
},
"elements": {
"link": {
"color": {
"text": "#0073aa"
}
}
},
"spacing": {
"padding": {
"top": "var(--wp--preset--spacing--50);",
"right": "var(--wp--preset--spacing--50)",
"bottom": "var(--wp--preset--spacing--50)",
"left": "var(--wp--preset--spacing--50)"
}
}
}
}
The group receives the class names is-style-section-1 and a unique class with a random string. The CSS is applied to the unique class:
<div class="wp-block-group is-style-section-1 has-global-padding is-layout-constrained wp-block-group-is-layout-constrained is-style-section-1--4890844408fc3663193fa1f59f87211b">
And in this example I am extending it to style heading blocks inside the group:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"title": "Light background",
"slug": "section-1",
"blockTypes": [ "core/group" ],
"styles": {
"blocks":{
"core/heading": {
"typography": {
"fontFamily": "var(--wp--preset--font-family--heading)"
}
}
},
"border": {
"radius": "4px"
},
"color": {
"background": "#FFF",
"text": "#111"
},
"elements": {
"link": {
"color": {
"text": "#0073aa"
}
}
},
"spacing": {
"padding": {
"top": "var(--wp--preset--spacing--50);",
"right": "var(--wp--preset--spacing--50)",
"bottom": "var(--wp--preset--spacing--50)",
"left": "var(--wp--preset--spacing--50)"
}
}
}
}
And here is how to register the same style for multiple blocks:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"title": "Post meta",
"slug": "section-1",
"blockTypes": [ "core/post-author-name", "core/post-date", "core/post-categories", "core/post-tags" ],
"styles": {
"color": {
"text": "#111"
},
"elements": {
"link": {
"color": {
"text": "#b52dcf"
}
}
},
"typography": {
"fontSize": "var(--wp--preset--font-size--small)"
}
}
}
Registering block styles using PHP
You can use the PHP function register_block_style()
to create a single block style or a section style. Place the function in your themes functions.php file, or use a separate file if you prefer. You need to use the function with the init
hook.
The parameters of register_block_style are:
- block_name: the block name including the name space, for example “core/paragraph”, From WordPress 6.6, this parameter also accepts an array of block names.
- style_properties: an array with required an optional properties:
- name: the unique identifier for the style (required). In the JSON equivalent, this is the slug for the style.
- label: the visible label of the style in the interface (required).
- style_handle: If you want to enqueue custom CSS from a separate stylesheet, you add the name of the style sheet here (optional). Note that you must enqueue the stylesheet in the editors and the front yourself.
- inline_style: If you want to add CSS inline, you add your CSS here, including the selector (optional).
If you are reading this lesson before WordPress 6.6 is released, the official documentation has not been updated yet. The new parameter added to the style properties in WordPress 6.6 is called style_data. You would only use of either style_handle, inline_style, or style_data.
The style data is an array of nested styles in a format that very closely resembles the styles section of theme.json. At the root level, the styles are applied to the block that you defined with the block_name. You style nested blocks and elements by adding them as keys to the array (See the code examples further down on this page).
Examples
First, you need to tell the function which block you want to style. In this example, I am using the core paragraph block. Add the prefix, core, and paragraph (the slug for the block), as the first argument:
register_block_style(
'core/paragraph',
Or, if you want to register the same style for more than one block, you need to use an array:
register_block_style(
array( 'core/paragraph', 'core/heading' ),
You are not limited to styling blocks from WordPress core. If you know the prefix and the slug, you can also style blocks from plugins.
The second argument is an array where you will add the name
, which is used in the CSS class that identifies your style, and the label
, which is the visible name in the block settings sidebar.
Using an inline style:
function prefix_register_block_styles() {
register_block_style(
array( 'core/paragraph', 'core/heading' ),
array(
'name' => 'prefix-rounded-corners',
'label' => __( 'Rounded corners', 'textdomain' ),
'inline_style' => '.is-style-prefix-rounded-corners {
border-radius: 4px;
background: #fafafa;
}',
)
);
}
add_action( 'init', 'prefix_register_block_styles' );
Using a style handle:
function prefix_register_block_styles() {
register_block_style(
array( 'core/paragraph', 'core/heading' ),
array(
'name' => 'prefix-rounded-corners',
'label' => __( 'Rounded corners', 'textdomain' ),
'style_handle' => 'prefix-rounded-corners',
)
);
}
add_action( 'init', 'prefix_register_block_styles' );
Using style data for a single block:
function prefix_register_block_styles() {
register_block_style(
'core/group',
array(
'name' => 'prefix-green-background',
'label' => __( 'Green background', 'textdomain' ),
'style_data' => array(
'color' => array(
'background' => 'green',
),
)
)
);
}
add_action( 'init', 'prefix_register_block_styles' );
Just like in the JSON style variation, you can use any valid CSS value. In this example I used a plain color name for the background, but you could also reference a CSS custom property.
Using style data for section styling (nested blocks and elements):
function prefix_register_block_styles() {
register_block_style(
'core/group',
array(
'name' => 'section-1',
'label' => __( 'Info', 'textdomain' ),
'style_data' => array(
'color' => array(
'background' => '#fafafa',
),
'blocks' => array(
'core/heading' => array(
'color' => array(
'background' => '#111',
'text' => '#fff',
),
),
),
)
)
);
}
add_action( 'init', 'prefix_register_block_styles' );
function prefix_register_block_styles() {
register_block_style(
'core/group',
array(
'name' => 'section-2',
'label' => __( 'Info (alt)', 'textdomain' ),
'style_data' => array(
'color' => array(
'background' => '#111',
'text' => '#fff',
),
'elements' => array(
'h2' => array(
'color' => array(
'text' => '#fafafa',
),
),
),
)
)
);
}
add_action( 'init', 'prefix_register_block_styles' );
If your CSS is complex, you may also need to escape certain characters:
'inline_style' => '.wp-block-separator.is-style-prefix-ornament {
mask-image: url(\'data:image/svg+xml; utf8, <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 81.52 29.9">
<path ... /></svg>\' );
}',
Registering block styles using JavaScript
Registering a custom block style with JavaScript is a two step process. You first need to register the style so that the option is available in the editors, and then enqueue the stylesheet in the editors and the front. This is why it is less common to use this method.
Create a new JavaScript file and enqueue it together with the following dependencies:wp-blocks
, wp-dom-ready
, and wp-edit-post
. Without these dependencies, your style with not work correctly.
Instead of using wp_enqueue_scripts
, you need to use enqueue_block_editor_assets
to load the scripts in the editors.
Example adapted from the official documentation:
function prefix_register_variations() {
wp_enqueue_script(
'prefix-block-variations',
get_stylesheet_directory_uri() . '/assets/js/variations.js',
array( 'wp-blocks', 'wp-dom-ready', 'wp-edit-post' ),
filemtime( plugin_dir_path( __FILE__ ) . '/assets/js/variations.js' )
);
}
add_action( 'enqueue_block_editor_assets', 'prefix_register_variations' );
If you are not familiar with filemtime
, the purpose here is to create a version number for the file used for development.
Create the JavaScript file variations.js and register the style using wp.blocks.registerBlockStyle
with the block name, the unique identifier, and the visible label:
wp.blocks.registerBlockStyle( 'core/quote', {
name: 'fancy-quote',
label: 'Fancy Quote',
} );
Add your CSS to a stylesheet that you enqueue in both the editors and the front. Remember that the generated CSS selector is is-style-
, followed the value of name: is-style-fancy-quote
.
How to unregister block styles
You can also unregister block styles. -This is a bit trickier than it needs to be, in my opinion: Styles registered with PHP can only be unregistered with PHP. Styles registered with JavaScript can only be unregistered with JavaScript.
To unregister a style with PHP, you need to use the function unregister_block_style()
. Include the prefixed block name (the slug), and the name of the style:
unregister_block_style( 'core/heading', 'prefix-rounded-corners' );
Depending on how the style is registered, you need to use an action hook that runs after the one used for the registration; Another reason why unregistering styles can be complicated. -You may need to search the source code to find when the style is registered.
Below is a JavaScript example from the advanced theme that I am using in the block theme generator:
function full_site_editing_unregister_block_style() {
wp_enqueue_script(
'full-site-editing-unregister',
get_stylesheet_directory_uri() . '/assets/js/unregister.js',
array( 'wp-blocks', 'wp-dom-ready', 'wp-edit-post' ),
FULL_SITE_EDITING_VERSION,
true
);
}
add_action( 'enqueue_block_editor_assets', 'full_site_editing_unregister_block_style' );
The JavaScript code in unregister.js
:
wp.domReady(() => {
wp.blocks.unregisterBlockStyle('core/quote', 'large');
wp.blocks.unregisterBlockStyle('core/quote', 'plain');
});
Naming
As you can see from the examples, I have used some different naming principles when adding the unique identifier (name if you are using PHP, and slug if you are using JSON).
The format for the generated class name is is-style-
followed by the value that you added to the name property: If the name is ‘section-1’, then the CSS class is ‘is-style-section-1.
There is no way to remove or customize ‘is-style-‘
I recommend using the names section-1, section-2 etc, for section styles to make it easier for users to switch themes. When a user applies a style, the class name is saved in the content in the WordPress database, and using the same class names improves the interoperability between our themes, and the user experience.
You can read discussions about naming custom styles on GitHub:
https://github.com/WordPress/gutenberg/issues/63036
https://github.com/WordPress/twentytwentyfive/issues/3
Additional notes
I have received questions about whether it is possible to select two block styles, but this is still not possible as of July 5, 2024. You can follow the discussion and progress on allowing multiple block styles here: Gutenberg #14598
Resources
Section Styles (The introduction post/dev note on WordPress.org)
Styling sections, nested elements, and more with Block Style Variations in WordPress 6.6