Environment
| Bricks | 2.4-beta2 |
| WordPress | 7.0.2 |
| MCP Adapter | 0.5.0 |
| Client | @automattic/mcp-wordpress-remote |
Summary
When an element’s _cssCustom contains a rule whose selector targets that same element with a structural pseudo-class, the MCP normalizer rewrites it into an equivalent-looking Bricks setting and drops the CSS. The resulting setting is never emitted as CSS, so the rule silently disappears from the rendered page.
Observed with:
#brxe-ztdfpi:nth-child(2n) {
flex-direction: row-reverse
}
which became:
"_direction:nth-child(2n)": "row-reverse"
The page’s generated stylesheet then contained zero occurrences of row-reverse. The layout effect — alternating the left/right order of every second item in a loop — was gone.
Evidence
The conversion is not a one-off, and it cannot be undone through the same API. Sending the correct CSS back while explicitly deleting the bogus setting:
{
"_cssCustom": "#brxe-ztdfpi:nth-child(2n) {\n flex-direction: row-reverse\n}",
"_direction:nth-child(2n)": null
}
returns, from dryRun:
"normalization": {
"changed": true,
"changedSettingsKeys": ["_cssCustom", "_direction:nth-child(2n)"]
},
"element": {
"settings": { "_direction:nth-child(2n)": "row-reverse" }
}
_cssCustom is discarded again and the dead setting is recreated. There is no way to store that rule on that element through MCP.
Scope: only self-targeting selectors
A rule doing the same job from the parent is left completely alone:
#brxe-usntku > div:nth-child(2n) {
flex-direction: row-reverse;
}
This survives verbatim and renders correctly. Only #brxe-<own-id>:pseudo is captured by the converter. Two loops on the same site, written the two different ways, behaved differently after identical MCP writes — one kept its alternating layout, the other lost it.
Steps to reproduce
- Add a Block with a query loop so it repeats.
- Give that block custom CSS targeting itself:
#brxe-<blockId>:nth-child(2n) { flex-direction: row-reverse } - Save in the builder and confirm the alternating layout renders.
- Through the MCP server, call
bricks/update-elementon that block — or on any element, since a page-wide save is enough. - Reload the frontend.
Expected
_cssCustom is stored as written and keeps rendering.
Actual
_cssCustom is replaced by _direction:nth-child(2n), no CSS is generated for it, and the alternating layout is lost. Nothing in the response marks this as destructive — changedSettingsKeys lists the keys, but does not say the rule will stop rendering.
Impact
Custom CSS is where users put exactly the things Bricks controls cannot express, so silently rewriting it is high-risk by nature. Here the visible result was a design detail — a deliberately non-monotonous alternating grid — reverting to a uniform layout on a live page, with no error anywhere.
Suggested fix
Either emit CSS for _direction:<pseudo> settings so the conversion is lossless, or stop converting _cssCustom altogether. Given that custom CSS is a deliberate escape hatch, leaving it untouched seems the safer default. If the conversion is kept, it should be verified round-trip: convert only when the resulting setting demonstrably produces the same CSS.
Workaround
Move the rule to the parent element and target the children, which the converter ignores:
#brxe-<parentId> > div:nth-child(2n) {
flex-direction: row-reverse;
}