From 997cf6752a94cd56b6c5669c0a2118f95291b7fc Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Mon, 15 Jun 2026 17:19:46 +0530 Subject: [PATCH 1/4] Fix: clear background-image when state sets solid background-color --- src/wp-includes/block-supports/states.php | 35 +++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/wp-includes/block-supports/states.php b/src/wp-includes/block-supports/states.php index 5220d060a731e..8b909a7b8f921 100644 --- a/src/wp-includes/block-supports/states.php +++ b/src/wp-includes/block-supports/states.php @@ -97,6 +97,40 @@ function wp_get_state_declarations_with_fallback_border_styles( $declarations ) return $declarations; } +/** + * Adds background reset declarations to prevent gradient/solid color conflicts. + * + * When a state sets a solid background-color, any gradient applied to the + * default state (via `background` shorthand or `background-image`) must be + * explicitly cleared. Without this, the gradient image layer remains visible + * on top of the solid hover color even when `!important` is used, because + * `background-color` and `background-image` are separate CSS properties. + * + * @param array $declarations CSS declarations generated by the style engine. + * @return array CSS declarations with background resets applied where needed. + */ +function wp_get_state_declarations_with_background_resets( $declarations ) { + if ( ! is_array( $declarations ) ) { + return $declarations; + } + + $has_background_color = isset( $declarations['background-color'] ) && '' !== $declarations['background-color']; + $has_background = isset( $declarations['background'] ) && '' !== $declarations['background']; + $has_background_image = isset( $declarations['background-image'] ) && '' !== $declarations['background-image']; + + /* + * When the state sets a solid background-color but no gradient of its own, + * emit `background-image: unset !important` to clear any gradient (whether + * stored as the `background` shorthand or as `background-image`) that was + * applied to the default / normal state via an inline style attribute. + */ + if ( $has_background_color && ! $has_background && ! $has_background_image ) { + $declarations['background-image'] = 'unset !important'; + } + + return $declarations; +} + /** * Adds a style fragment to a selector-keyed state style group. * @@ -461,6 +495,7 @@ function wp_render_block_states_support( $block_content, $block ) { : $value . ' !important'; } $declarations = wp_get_state_declarations_with_fallback_border_styles( $declarations ); + $declarations = wp_get_state_declarations_with_background_resets( $declarations ); $style_rule = array( 'selector' => wp_build_state_selector( ".$unique_class", From e55517ba7384617bd965913e979cc5490f59c518 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Mon, 15 Jun 2026 17:22:45 +0530 Subject: [PATCH 2/4] Tests: add tests for clearing background-image state --- tests/phpunit/tests/block-supports/states.php | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/tests/phpunit/tests/block-supports/states.php b/tests/phpunit/tests/block-supports/states.php index 83bace976277d..52eaec7e63937 100644 --- a/tests/phpunit/tests/block-supports/states.php +++ b/tests/phpunit/tests/block-supports/states.php @@ -136,6 +136,85 @@ public function test_preserves_authored_border_style_declarations() { ); } + /** + * Tests that background-image reset is added when a state sets a solid background-color. + * + * @covers ::wp_get_state_declarations_with_background_resets + */ + public function test_adds_background_image_reset_for_solid_background_color() { + $actual = wp_get_state_declarations_with_background_resets( + array( + 'background-color' => '#ff0000 !important', + ) + ); + + $this->assertSame( + array( + 'background-color' => '#ff0000 !important', + 'background-image' => 'unset !important', + ), + $actual + ); + } + + /** + * Tests that background-image reset is not added when the state also sets a legacy gradient. + * + * @covers ::wp_get_state_declarations_with_background_resets + */ + public function test_no_background_image_reset_when_state_sets_legacy_gradient() { + $actual = wp_get_state_declarations_with_background_resets( + array( + 'background-color' => '#ff0000 !important', + 'background' => 'linear-gradient(135deg, #ff0000, #0000ff) !important', + ) + ); + + $this->assertSame( + array( + 'background-color' => '#ff0000 !important', + 'background' => 'linear-gradient(135deg, #ff0000, #0000ff) !important', + ), + $actual + ); + } + + /** + * Tests that background-image reset is not added when the state also sets a modern gradient. + * + * @covers ::wp_get_state_declarations_with_background_resets + */ + public function test_no_background_image_reset_when_state_sets_modern_gradient() { + $actual = wp_get_state_declarations_with_background_resets( + array( + 'background-color' => '#ff0000 !important', + 'background-image' => 'linear-gradient(135deg, #ff0000, #0000ff) !important', + ) + ); + + $this->assertSame( + array( + 'background-color' => '#ff0000 !important', + 'background-image' => 'linear-gradient(135deg, #ff0000, #0000ff) !important', + ), + $actual + ); + } + + /** + * Tests that declarations without background-color are returned unchanged. + * + * @covers ::wp_get_state_declarations_with_background_resets + */ + public function test_no_background_reset_when_no_background_color() { + $input = array( + 'color' => '#ff0000 !important', + ); + $actual = wp_get_state_declarations_with_background_resets( $input ); + + $this->assertSame( $input, $actual ); + } + /** * Tests that modifier classes on the first compound selector are preserved * when state selectors are scoped to the block wrapper. From 5f175f2c1829b7b914cde259db5735e9bc1a493b Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Mon, 15 Jun 2026 21:01:56 +0530 Subject: [PATCH 3/4] Tests: fix unit tests --- tests/phpunit/tests/block-supports/states.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/block-supports/states.php b/tests/phpunit/tests/block-supports/states.php index 52eaec7e63937..0325503db47bc 100644 --- a/tests/phpunit/tests/block-supports/states.php +++ b/tests/phpunit/tests/block-supports/states.php @@ -914,7 +914,7 @@ public function test_responsive_pseudo_state_generates_media_query_scoped_css() $actual_stylesheet = wp_style_engine_get_stylesheet_from_context( 'block-supports', array( 'prettify' => false ) ); $this->assertStringContainsString( - '@media (width <= 480px){.' . $matches[0] . ' .wp-block-button__link:hover{background-color:#ff00d0 !important;}}', + '@media (width <= 480px){.' . $matches[0] . ' .wp-block-button__link:hover{background-color:#ff00d0 !important;background-image:unset !important;}}', $actual_stylesheet ); } From 9110b32b8bf9207dd6a49ebac21621bfa5e23d3f Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Tue, 16 Jun 2026 11:29:39 +0530 Subject: [PATCH 4/4] Chore: update function doc --- src/wp-includes/block-supports/states.php | 2 ++ tests/phpunit/tests/block-supports/states.php | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/wp-includes/block-supports/states.php b/src/wp-includes/block-supports/states.php index 8b909a7b8f921..787a55b659814 100644 --- a/src/wp-includes/block-supports/states.php +++ b/src/wp-includes/block-supports/states.php @@ -106,6 +106,8 @@ function wp_get_state_declarations_with_fallback_border_styles( $declarations ) * on top of the solid hover color even when `!important` is used, because * `background-color` and `background-image` are separate CSS properties. * + * @since 7.1.0 + * * @param array $declarations CSS declarations generated by the style engine. * @return array CSS declarations with background resets applied where needed. */ diff --git a/tests/phpunit/tests/block-supports/states.php b/tests/phpunit/tests/block-supports/states.php index 0325503db47bc..1d1e6da33408d 100644 --- a/tests/phpunit/tests/block-supports/states.php +++ b/tests/phpunit/tests/block-supports/states.php @@ -140,6 +140,8 @@ public function test_preserves_authored_border_style_declarations() { * Tests that background-image reset is added when a state sets a solid background-color. * * @covers ::wp_get_state_declarations_with_background_resets + * + * @ticket 65239 */ public function test_adds_background_image_reset_for_solid_background_color() { $actual = wp_get_state_declarations_with_background_resets( @@ -161,6 +163,8 @@ public function test_adds_background_image_reset_for_solid_background_color() { * Tests that background-image reset is not added when the state also sets a legacy gradient. * * @covers ::wp_get_state_declarations_with_background_resets + * + * @ticket 65239 */ public function test_no_background_image_reset_when_state_sets_legacy_gradient() { $actual = wp_get_state_declarations_with_background_resets( @@ -183,6 +187,8 @@ public function test_no_background_image_reset_when_state_sets_legacy_gradient() * Tests that background-image reset is not added when the state also sets a modern gradient. * * @covers ::wp_get_state_declarations_with_background_resets + * + * @ticket 65239 */ public function test_no_background_image_reset_when_state_sets_modern_gradient() { $actual = wp_get_state_declarations_with_background_resets( @@ -205,6 +211,8 @@ public function test_no_background_image_reset_when_state_sets_modern_gradient() * Tests that declarations without background-color are returned unchanged. * * @covers ::wp_get_state_declarations_with_background_resets + * + * @ticket 65239 */ public function test_no_background_reset_when_no_background_color() { $input = array(