Advanced Styling: Elements inside Block Style Variations
A common challenge in block themes is "Contextual Styling." For example, creating a "Dark Mode" style for a Group block where the background turns black, but the text and links must turn white (overriding the global blue link color).
With theme.json Version 3 (WordPress 6.6+), you can nest elements inside your block style variation definition.
1. The Scenario
You want to create a block style for the Group block called "Night Mode".
- Background: Black
- Text: White
- Links: Cyan (instead of the global default Blue)
- Links on Hover: White
2. The Solution: Nesting elements
You define the variation in styles.blocks.[block].variations. The key is to place the elements object inside the style object of that variation.
File: theme.json
{
"version": 3,
"styles": {
"blocks": {
"core/group": {
"variations": [
{
"name": "night-mode",
"label": "Night Mode",
"style": {
"color": {
"background": "var(--wp--preset--color--black)",
"text": "var(--wp--preset--color--white)"
},
"elements": {
"link": {
"color": {
"text": "var(--wp--preset--color--cyan)"
},
":hover": {
"color": {
"text": "var(--wp--preset--color--white)"
}
}
},
"heading": {
"color": {
"text": "var(--wp--preset--color--white)"
}
}
}
}
}
]
}
}
}
}
3. How It Compiles
WordPress acts as a compiler here. It generates highly specific CSS selectors that scope your element styles to the variation class.
Generated CSS (Approximate):
/* The Wrapper */
.wp-block-group.is-style-night-mode {
background-color: var(--wp--preset--color--black);
color: var(--wp--preset--color--white);
}
/* The Nested Element */
.wp-block-group.is-style-night-mode a {
color: var(--wp--preset--color--cyan);
}
4. Why This Matters
Before this feature, you had to write custom CSS in a separate stylesheet to target .is-style-night-mode a. Now, your entire style logic remains encapsulated within theme.json, ensuring the editor matches the front end perfectly without extra request overhead.
5. Supported Elements
You can target any standard element supported by theme.json:
link(<a>)heading(<h1>-<h6>)button(<button>,.wp-element-button)caption(figcaption)cite(cite)