WordPress 7.0 adds Custom CSS for individual block instances, and it is late. Since 6.2, styling one block meant a two-step dance: add a CSS class in the Advanced panel, then go and find the Global Styles panel to write the actual rule. The field now sits on the block you are editing.
I have spent 14 years around WordPress and I have lost count of the sites carrying a pile of one-off CSS classes that nobody dares delete. That is the debt this feature pays down. You write the rule in the block inspector, in the same scoped syntax the Site Editor already uses.
The problem with the old way
Say you wanted one specific Heading block to have its own hover effect. You added an Additional CSS Class in the Advanced panel, then opened the Site Editor’s global Custom CSS field and wrote the rules over there. It was fragile, and it was out of reach for any editor without full admin permissions.
Most users never found that path. Plenty of them installed a heavy styling plugin instead, to do something core should have handled. I wrote about where the styling system has been heading in an earlier post on native block CSS and layout fixes.
How Custom CSS for individual block instances works
Under the hood, WordPress registers a new customCSS support. Whatever you type into the field is saved as an attribute, inside the block’s style attribute under the css key.
<!-- wp:heading {"style":{"css":"&:hover { color: orange; }\n"}} -->
<h2 class="wp-block-heading has-custom-css">Dynamic Heading</h2>
<!-- /wp:heading -->
At render time WordPress generates a hash-based class for that one instance, so the rules cannot leak into another block. The frontend output ends up looking like this:
<style id="wp-block-custom-css">
:root :where(.wp-custom-css-8841bf3c3cc9) {
color: blue;
}
</style>
<h2 class="wp-block-heading has-custom-css wp-custom-css-8841bf3c3cc9">Heading</h2>
The generated stylesheet is registered with a dependency on global-styles, so instance-level CSS wins over the defaults. Same idea as WordPress 7.0 dimensions support, which handles layout controls without an external stylesheet.
Opting out, and custom blocks
If you write blocks, some of them will break the moment a root-level class gets added, with raw HTML and shortcode wrappers the usual suspects. You can opt those out in block.json.
{
"supports": {
"customCSS": false
}
}
For server-rendered blocks, WordPress injects the classes with WP_HTML_Tag_Processor rather than a regex pass over the markup. The details are in PR #73959 and the official Block Supports API reference.
If this kind of block styling work is eating your dev hours, I can take it on. I have been building on WordPress since the 4.x days.
The takeaway
WordPress 7.0 finally gives us the granularity, and Custom CSS for individual block instances means the Additional CSS workaround can go. One caution: a field that is easy to reach is also an easy way to scatter twenty near-identical rules across one page, so site-wide decisions still belong in Global Styles. The official dev note has the rest.