Style states: Fix phantom pseudo element style output - #81291
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
| if ( ! $has_element_pseudo ) { | ||
| foreach ( array_keys( $responsive_media_queries ) as $bp ) { | ||
| if ( isset( $theme_json['styles']['blocks'][ $name ][ $bp ]['elements'][ $element ][ $pseudo_selector ] ) ) { | ||
| $has_element_pseudo = true; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
This is the code that causes the issue. When there's no pseudo style on the base it then checks the breakpoints, and sets has_element_pseudo to true, but then creates a node that doesn't have the right path.
I expect it was accidentally left in during refactoring and other changes.
| if ( $include_node_paths_only ) { | ||
| $nodes[] = array( | ||
| 'path' => $element_pseudo_path, | ||
| ); | ||
| continue; | ||
| } |
There was a problem hiding this comment.
This is dead code as explained in the PR description.
05f74e3 to
7bf3b6d
Compare
0852368 to
bf1aadb
Compare
tellthemachines
left a comment
There was a problem hiding this comment.
Thanks for fixing this, LGTM!
…nodes In get_block_nodes(), the element loop continues before reaching the pseudo-selector loop when include_node_paths_only is set, so the path-only branch inside the pseudo loop can never execute.
When an element's pseudo state was styled only inside a breakpoint,
get_block_nodes() still emitted the default pseudo node.
get_styles_for_block() then fell back to the element's base styles,
outputting a rule the theme never defined, e.g.:
:root :where(.wp-block-group a):hover{color: blue;}
Emit the default pseudo node only when the default state styles the
pseudo, matching the block-level pseudo handling. The per-breakpoint
pseudo nodes already guard themselves.
|
Rebased locally, will push soon, but wanted to add that LGTM Before:root :where(.wp-block-group a:where(:not(.wp-element-button))){color: pink;}
:root :where(.wp-block-group a:where(:not(.wp-element-button)):hover){color: pink;}
@media (width <= 480px){:root :where(.wp-block-group a:where(:not(.wp-element-button)):hover){color: green;}}After:root :where(.wp-block-group a:where(:not(.wp-element-button))){color: pink;}
@media (width <= 480px){:root :where(.wp-block-group a:where(:not(.wp-element-button)):hover){color: green;}} |
bf1aadb to
5927306
Compare
Co-authored-by: talldan <talldanwp@git.wordpress.org> Co-authored-by: tellthemachines <isabel_brison@git.wordpress.org> Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
|
I just cherry-picked this PR to the wp/7.1 branch to get it included in the next release: 96f4b74 |
Note: PR is based on the branch from #81265. It relies on the changes there.
What?
Fixes an issue where an incorrect pseudo style would be output (copying the base element's style) whenever a responsive+pseudo style was set for the element (but no pseudo style itself).
Why?
With an element styled at its root and its pseudo styled only inside a responsive state like
@mobile:{ "styles": { "blocks": { "core/group": { "elements": { "link": { "color": { "text": "blue" } } }, "@mobile": { "elements": { "link": { ":hover": { "color": { "text": "darkred" } } } } } } } } }CSS like this would be incorrectly produced:
The pseudo node defined by the responsive style was being included as part of the root.
get_styles_for_block()falls back to the element's base styles when the pseudo key is absent — outputting a rule the theme never defined.How?
Only output the default pseudo rule when the pseudo is styled outside a breakpoint — the same check the block-level pseudo styles already use. The breakpoint rules already decide this per breakpoint, so they're untouched.
PR also separately removes some dead code:
The code inside the if statement is unreachable because there's a similar
continuestatement earlier in the loop:gutenberg/lib/class-wp-theme-json-gutenberg.php
Lines 3709 to 3714 in 7c36647
Testing Instructions
On trunk - the block has a rogue style like this:
In this PR - the block doesn't have that style
Use of AI Tools
OpenCode / Kimi K3