Make WordPress Core

Opened 43 hours ago

Last modified 42 hours ago

#66252 new defect (bug)

State Styles: Scope per-instance rules to the block's root element

Reported by: aaronrobertshaw Owned by:
Priority: normal Milestone: 7.2
Component: Editor Version: trunk
Severity: normal Keywords: gutenberg-merge has-patch has-unit-tests
Cc: Focuses:

Description

Backport of Gutenberg PR ​https://github.com/WordPress/gutenberg/pull/83986.
Related: ​https://github.com/WordPress/gutenberg/pull/83925

Fixes per-instance state styles on blocks whose root selector starts with another block's class. List Item registers .wp-block-list > li, and the instance class that scopes a state rule sits on the li itself, so swapping the leading compound for that class produced .wp-states-xxxx > li, which matches nothing. A breakpoint value set on a list item was written to the stylesheet but never applied.

The fix keeps a leading compound that names a different block as an ancestor and puts the instance class on the block's own compound, giving .wp-block-list > .wp-states-xxxx. A leading compound followed by a wp-block-* class still describes a nested element, as in .wp-block-button .wp-block-button__link, so those selectors keep the existing behaviour.

Change History (1)

This ticket was mentioned in ​PR #14039 on ​WordPress/wordpress-develop by ​@aaronrobertshaw.


42 hours ago
#1

  • Keywords has-patch has-unit-tests added

Backport of Gutenberg PR ​https://github.com/WordPress/gutenberg/pull/83986

Trac ticket: https://core.trac.wordpress.org/ticket/66252

Per-instance state styles never applied to a block whose root selector starts with another block's class. List Item registers .wp-block-list > li, so scoping swapped .wp-block-list for the instance class and emitted .wp-states-xxxx > li, which matches nothing. The instance class is on the li itself.

This PR backports:

  • a new wp_get_state_selector_ancestor() that returns the leading compound and its combinator when that compound names a different block,
  • a $block_name parameter on wp_build_state_selector() so the ancestor is kept and the instance class lands on the block's own compound,
  • and the accompanying states block support tests, including one that reads core/list-item's registered selectors rather than a literal.

Testing instructions

Only the front end can be exercised here, since the editor half is not in Core yet. :hover is not a valid state for List Item (WP_Theme_JSON::VALID_BLOCK_PSEUDO_SELECTORS lists Button and Navigation Link only), so use a breakpoint state.

  1. Activate a block theme.
  2. Add a post, switch to the code editor, and paste:
<ul class="wp-block-list">
<li>Narrow me</li>


<li>Second item</li>
</ul>
  1. Publish and view the post. Narrow the window below 480px. The first item turns pink, the second does not.
  2. View source and find the generated rule:
@media (width <= 480px){.wp-block-list > .wp-states-9f0f8a0d{color:#ff00d0 !important;}}

Without the patch the same markup emits .wp-states-9f0f8a0d > li, which matches nothing, so the item stays its normal colour at any width.

  1. Check a block whose root selector is its own class is unaffected. Give a Button a :hover colour the same way and confirm it still works.

Use of AI

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: the mechanical port and the test port; I reviewed and verified both.

Note: See TracTickets for help on using tickets.