WordPress 6.6, expected to be released on July 16, 2024, is set to bring the biggest overhaul to block style variations (block styles, for short) in a long while. These changes will make block styles one of the most powerful tools in your theme developer toolbox.
As the 6.6 development cycle wraps up in the coming weeks, you’ll often see these changes referred to as “section styles.” While this is a part of the updated feature set (and I’ll dive into this later in this post), it doesn’t accurately reflect how important this release is for theme authors.
I have already cut 100s of lines of custom CSS code from my theme, transferring it to the standard theme.json
file. Being able to place most of my style-related code under a single, standardized system cannot be understated.
On top of that, the new nesting capabilities solve several workarounds that I’ve had to employ in my own theme work (I’ll get into those too).
Let’s just dive right into the updates to the block style variations system.
Table of Contents
Customizing block style variations via theme.json
In 2023, WordPress 6.3 introduced the ability to edit Core-registered block style variations via theme.json
. This was a nice first step, but it wasn’t an overly exciting upgrade to the theming experience since the power of block style variations is in those that you create yourself. For all intents and purposes, this meant that most use cases required custom CSS.
WordPress 6.6 will let you style any registered block style variations in theme.json
. Just like with Core variations, you can target your custom variations via the styles.blocks.blockName.variations
property.
I don’t want to downplay the other updates too much, but this change alone is where you’ll cut back the most on custom CSS.
Let’s give it a try. In the screenshot below, you’ll see that I’ve designed a Boxed style variation for the Pullquote block:
As you’ve always done, you’ll need to register custom block style variations via PHP or JavaScript. In this case, you’ll use the PHP method, so first add a registration callback function hooked to init
in your theme’s functions.php
file:
add_action( 'init', 'themeslug_register_block_styles' );
function themeslug_register_block_styles() {
// Add calls to register_block_style() here.
}
You’ll use this function for registering custom variations throughout the rest of this tutorial.
Now add this code inside of your themeslug_register_block_styles()
function to register the Boxed block style variation:
register_block_style( 'core/pullquote', [
'name' => 'boxed',
'label' => __( 'Boxed', 'themeslug' )
] );
In the past, you may have used the inline_style
property of register_block_style()
or output some custom CSS in some other way, such as a block stylesheet. But now you can register the style variation and move your actual style code to your theme.json
file.
For the Boxed variation, let’s just stick with border and spacing styles (feel free to customize further to match your theme). Integrate the following code into your theme.json
file:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"styles": {
"blocks": {
"core/pullquote": {
"variations": {
"boxed": {
"border": {
"color": "currentColor",
"style": "solid",
"width": "6px"
},
"spacing": {
"padding": {
"top": "var:preset|spacing|60",
"bottom": "var:preset|spacing|60",
"left": "var:preset|spacing|60",
"right": "var:preset|spacing|60"
}
}
}
}
}
}
}
}
Note that the code for the variation goes directly under styles.blocks.core/pullquote.variations.boxed
. You can include multiple variations for each block under its variations
property.
The JSON above and throughout this tutorial uses the new version 3 theme.json
schema, which is only supported for WordPress 6.6+ or when using the Gutenberg plugin alongside an older version of WordPress.
Styling nested elements and blocks
Being able to add block style variations to theme.json
solves a lot of problems on its own, mostly around standardization. But WordPress 6.6 also kicks this up a notch and lets you style elements and blocks that are nested inside of your custom variations. This will open the door to a near-unlimited canvas to paint via theme.json
.
Let’s take a look at how this works via a block style variation on the Post Terms (Categories) block. As shown in the following screenshot, you’ll see that the block has the Buttons block style and the individual category links look like buttons:
This design is now possible using theme.json
because you can target the link elements nested within the Post Terms block.
To give this variation a test, add this code inside your themeslug_register_block_styles()
function in functions.php
:
register_block_style( 'core/post-terms', [
'name' => 'buttons',
'label' => __( 'Buttons', 'themeslug' )
] );
Just like in the previous section, you’ll target the variations.variationName
property of the block you’re adding the variation to in theme.json
. However, to style nested elements, you’ll want to go a couple levels deeper and target elements.elementName
.
Integrate the following code into your theme’s theme.json
file:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"styles": {
"blocks": {
"core/post-terms": {
"variations": {
"buttons": {
"elements": {
"link": {
"color": {
"background": "var:preset|color|contrast",
"text": "var:preset|color|base"
},
"spacing": {
"padding": {
"top": "var:preset|spacing|20",
"bottom": "var:preset|spacing|20",
"left": "var:preset|spacing|40",
"right": "var:preset|spacing|40"
}
},
"typography": {
"textDecoration": "none"
}
}
},
"css": "& .wp-block-post-terms__separator { display: none; }"
}
}
}
}
}
}
As shown above, the code specifically targets elements.link
for the buttons
variation. You can also customize nested blocks via the blocks.blockName
property for this variation (assuming it supports nested blocks).
You may have noticed that the code included a css
property for the variation. Yes, you can add custom CSS for block style variations in your theme.json
! In this case, it was used to hide the separator between post terms, targeting this specific variation.
Sections styles and new registration methods
“Sections styles” refer to a concept that is being introduced in WordPress 6.6. In essence, a section is just a block style variation and any nested elements and blocks that you can customize via the theme.json
system.
Wait…isn’t that what was just covered above? Mostly, yes.
But the foundational concepts that led to section styles opened some new features within the block style variations system:
- You can register new
theme.json
objects for these variations via:- A custom
/styles/*.json
file. - The
register_block_style()
PHP function.
- A custom
- You can register them for multiple blocks at once (e.g., Group, Columns, etc.).
While the new terminology may sound like a fresh marketing spin on an old feature, there are very real benefits. But at the end of the day, it’s just an extension of what’s currently possible with block style variations.
The primary goal of section styles is to use them for actual sections that need to be designed differently than your primary theme.json
styles. Imagine if you wanted to quickly switch between color sets for different sections as shown in this screenshot:
That’s easy enough to do with the design tools in the block inspector (sidebar), but it’s not easy to update across a site when the design changes. That’s where block style variations shine.
And when you mix this with nested element and block designs, you can essentially create full-blown theme.json
style sets for specific sections. For example, you could even create section-specific (nested) styles for the Heading, Paragraph, Image, and Blockquote blocks used in either of those sections to make them even more unique.
This can come in handy when creating a standardized, updateable design system for client sites, for example.
Registering block/section style variations
There are two methods of registering section styles, as noted earlier. The primary method is to create a new JSON file under the /styles
folder in your theme. This way, you can manage them as separate entities. But follow along to learn how each method works.
Registering via JSON files
In the past, you could only add global style variation JSON files to your theme’s /styles
folder, but that is changing in WordPress 6.6. You’ll now be able to add global, block, color, and typography variations to this folder.
To not confuse the different types of style variations, I recommend organizing your /styles
folder using a structure similar to this (WordPress will automatically look in sub-folders):
/styles
/block
or/section
/color
/global
/typography
Color and typography style variations are a new feature coming in WordPress 6.6. They’ll be covered here on the Developer Blog, but they are outside the scope of this post.
With this organizational system in mind, create a new /styles/block/section-1.json
file and put this code in the file:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"slug": "section-1",
"title": "Section 1",
"blockTypes": [ "core/group", "core/columns" ],
"styles": {
"color": {
"background": "var:preset|color|contrast",
"text": "var:preset|color|base"
}
}
}
This will create the “Section 1” block style variation from the above screenshot (the colors may be different, depending on your theme).
You should also take note of a few key properties defined in the JSON:
slug
: A unique slug for your section, which can contain alphanumeric characters, hyphens, or underscores.title
: A title for your section that will be shown to screen readers. This is used to automatically register your variation if no slug is present (e.g.,Section 1
becomessection-1
).blockTypes
: An array of block types that this style variation should apply to (you’re no longer limited to a single block type).
This section style is an overly simple example for demonstration purposes. It’s possible to flesh this out to include styles for every element and block that WordPress supports, styling them when they are used within this block. It’s for this reason that these types of variations may best be used for container-type blocks, such as Group, Columns, and Cover.
Now add a /styles/block/section-2.json
file in your theme to make a Section 2 block style variation. You can use the following code, but mix up the colors to your liking:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"slug": "section-2",
"title": "Section 2",
"blockTypes": [ "core/group", "core/columns" ],
"styles": {
"color": {
"background": "#cbd5e1",
"text": "var:preset|color|contrast"
}
}
}
Registering via PHP
The third option for registering a section style (or any block style variation) is with PHP. There are two primary changes to the register_block_style()
function that make this possible:
- The first parameter,
$block_name
, now accepts an array of block types (you can still pass a string for a single block type). - The second parameter,
$style_properties
, has a newstyle_data
key that accepts an array of data that should be formatted like its JSON counterpart.
To register the Section 1 block style variation via PHP instead of JSON, add this code inside your themeslug_register_block_styles()
function in functions.php
:
register_block_style(
[ 'core/group', 'core/columns' ],
[
'name' => 'section-1',
'label' => __( 'Section 1', 'themeslug' ),
'style_data' => [
'color' => [
'background' => 'var:preset|color|contrast',
'text' => 'var:preset|color|base'
]
]
]
);
Of course, you can repeat this process for Section 2 and other custom variations you build.
Overwriting via global style variations
Originally, it was possible to register block style variations via theme.json
or custom global style variation JSON files. However, based on ongoing discussions, registering using this method was removed in Gutenberg 18.7 and WordPress trunk.
This method can style be used to overwrite section styles via global style variation JSON files. However, based on the results of the discussion, this could change in WordPress 6.7 and beyond. Keep an eye on the ticket to stay updated.
WordPress 6.6 also adds a new styles.variations
property (this property was previously styles.blocks.variations
) for overwriting section styles within global style variations.
The difference here is really in the formatting when compared to a block style variation JSON file. You must pass the variation slug (e.g., section-1
) as a key and the variation’s styles as the value under the variations
property. Take a look at the same Section 1 variation you registered earlier when overwriting it via a global style variation JSON file:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"styles": {
"variations": {
"section-1": {
"color": {
"background": "#22737c",
"text": "#ffffff"
}
}
}
}
}
A section style with nested block customization
Now, let’s look at a more practical example of section styles that I’ve used in my theme. It customizes nested blocks.
One of the design touches I wanted to add to my theme was to give the Post Author Name block a different font family and style when used in a specific context. It’s a simple thing, but it made me happy. You can see this small design change in the template view in this screenshot (compare the Post Author Name Block’s typography to that of the Post Date and Categories blocks):
I’ve done this by creating a Post Byline block style variation. Then I specifically targeted the Post Author Name block to give it unique typography that looks different from the rest of the blocks used in the byline. I also changed the text-decoration
of all link elements for this variation.
To give this a try, create a new file named /styles/block/post-byline.json
in your theme. Then add the following code to it (note that you may need to change the fontFamily
reference to match one of your theme’s fonts):
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"title": "Post Byline",
"blockTypes": [ "core/group" ],
"styles": {
"elements": {
"link": {
"typography": {
"textDecoration": "none"
},
":focus": {
"typography": {
"textDecoration": "underline"
}
},
":hover": {
"typography": {
"textDecoration": "underline"
}
}
}
},
"blocks": {
"core/post-author-name": {
"typography": {
"fontFamily": "var:preset|font-family|primary",
"fontStyle": "italic"
}
}
}
}
}
I could showcase dozens of examples of where this has helped me overhaul my theme and take a new approach to styling sections of blocks. But I am limited by the nature of a written tutorial.
I hope that these few examples provide a good starting point for you with your own designs. There is so much more that you can do, and I welcome you to share what you’ve built on top of this new system.
Related WordPress CSS changes
The upgrades to block style variations meant overhauling how Core generated block styles and reducing their specificity. If you have block-specific custom CSS in your theme, there is a chance that these changes will impact your custom styles in some way. But they will also let you use theme.json
for many more use cases.
For a more detailed overview of the changes that led to this update, read the Dev Note: WordPress 6.6 CSS Specificity. You can also dive into the tickets where discussions and changes occurred:
- Block Styles: Extend block style variations as mechanism for achieving section styling
- CSS Specificity for WordPress 6.6
- Section Styling, Colorways, and Typesets for WP 6.6
- Styles: try wrapping with :root to fix reset styles
- Try reducing specificity of global styles selectors only
- Reduce specificity of block library styles conflicting with block supports
- Section styles: consolidate variation name
These CSS changes were necessary to push forward with new features and clean up quite a few older issues. On the whole, they should make styling blocks much cleaner and significantly decrease the amount of custom CSS you need.
Props to @ndiego and @colorful-tones for feedback and review on this post.
Leave a Reply