Skip to content

Commit 5a916f0

Browse files
Editor: fix background color and image incompatibility in state styles.
Unsets any existing background-image if background color is applied as a viewport state. Props iamchitti, isabel_brison. Fixes #65239. git-svn-id: https://develop.svn.wordpress.org/trunk@62506 602fd350-edb4-49c9-b593-d223f7449a82
1 parent f7baebc commit 5a916f0

2 files changed

Lines changed: 125 additions & 1 deletion

File tree

src/wp-includes/block-supports/states.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,42 @@ function wp_get_state_declarations_with_fallback_border_styles( $declarations )
9797
return $declarations;
9898
}
9999

100+
/**
101+
* Adds background reset declarations to prevent gradient/solid color conflicts.
102+
*
103+
* When a state sets a solid background-color, any gradient applied to the
104+
* default state (via `background` shorthand or `background-image`) must be
105+
* explicitly cleared. Without this, the gradient image layer remains visible
106+
* on top of the solid hover color even when `!important` is used, because
107+
* `background-color` and `background-image` are separate CSS properties.
108+
*
109+
* @since 7.1.0
110+
*
111+
* @param array $declarations CSS declarations generated by the style engine.
112+
* @return array CSS declarations with background resets applied where needed.
113+
*/
114+
function wp_get_state_declarations_with_background_resets( $declarations ) {
115+
if ( ! is_array( $declarations ) ) {
116+
return $declarations;
117+
}
118+
119+
$has_background_color = isset( $declarations['background-color'] ) && '' !== $declarations['background-color'];
120+
$has_background = isset( $declarations['background'] ) && '' !== $declarations['background'];
121+
$has_background_image = isset( $declarations['background-image'] ) && '' !== $declarations['background-image'];
122+
123+
/*
124+
* When the state sets a solid background-color but no gradient of its own,
125+
* emit `background-image: unset !important` to clear any gradient (whether
126+
* stored as the `background` shorthand or as `background-image`) that was
127+
* applied to the default / normal state via an inline style attribute.
128+
*/
129+
if ( $has_background_color && ! $has_background && ! $has_background_image ) {
130+
$declarations['background-image'] = 'unset !important';
131+
}
132+
133+
return $declarations;
134+
}
135+
100136
/**
101137
* Adds a style fragment to a selector-keyed state style group.
102138
*
@@ -461,6 +497,7 @@ function wp_render_block_states_support( $block_content, $block ) {
461497
: $value . ' !important';
462498
}
463499
$declarations = wp_get_state_declarations_with_fallback_border_styles( $declarations );
500+
$declarations = wp_get_state_declarations_with_background_resets( $declarations );
464501
$style_rule = array(
465502
'selector' => wp_build_state_selector(
466503
".$unique_class",

tests/phpunit/tests/block-supports/states.php

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,93 @@ public function test_preserves_authored_border_style_declarations() {
136136
);
137137
}
138138

139+
/**
140+
* Tests that background-image reset is added when a state sets a solid background-color.
141+
*
142+
* @covers ::wp_get_state_declarations_with_background_resets
143+
*
144+
* @ticket 65239
145+
*/
146+
public function test_adds_background_image_reset_for_solid_background_color() {
147+
$actual = wp_get_state_declarations_with_background_resets(
148+
array(
149+
'background-color' => '#ff0000 !important',
150+
)
151+
);
152+
153+
$this->assertSame(
154+
array(
155+
'background-color' => '#ff0000 !important',
156+
'background-image' => 'unset !important',
157+
),
158+
$actual
159+
);
160+
}
161+
162+
/**
163+
* Tests that background-image reset is not added when the state also sets a legacy gradient.
164+
*
165+
* @covers ::wp_get_state_declarations_with_background_resets
166+
*
167+
* @ticket 65239
168+
*/
169+
public function test_no_background_image_reset_when_state_sets_legacy_gradient() {
170+
$actual = wp_get_state_declarations_with_background_resets(
171+
array(
172+
'background-color' => '#ff0000 !important',
173+
'background' => 'linear-gradient(135deg, #ff0000, #0000ff) !important',
174+
)
175+
);
176+
177+
$this->assertSame(
178+
array(
179+
'background-color' => '#ff0000 !important',
180+
'background' => 'linear-gradient(135deg, #ff0000, #0000ff) !important',
181+
),
182+
$actual
183+
);
184+
}
185+
186+
/**
187+
* Tests that background-image reset is not added when the state also sets a modern gradient.
188+
*
189+
* @covers ::wp_get_state_declarations_with_background_resets
190+
*
191+
* @ticket 65239
192+
*/
193+
public function test_no_background_image_reset_when_state_sets_modern_gradient() {
194+
$actual = wp_get_state_declarations_with_background_resets(
195+
array(
196+
'background-color' => '#ff0000 !important',
197+
'background-image' => 'linear-gradient(135deg, #ff0000, #0000ff) !important',
198+
)
199+
);
200+
201+
$this->assertSame(
202+
array(
203+
'background-color' => '#ff0000 !important',
204+
'background-image' => 'linear-gradient(135deg, #ff0000, #0000ff) !important',
205+
),
206+
$actual
207+
);
208+
}
209+
210+
/**
211+
* Tests that declarations without background-color are returned unchanged.
212+
*
213+
* @covers ::wp_get_state_declarations_with_background_resets
214+
*
215+
* @ticket 65239
216+
*/
217+
public function test_no_background_reset_when_no_background_color() {
218+
$input = array(
219+
'color' => '#ff0000 !important',
220+
);
221+
$actual = wp_get_state_declarations_with_background_resets( $input );
222+
223+
$this->assertSame( $input, $actual );
224+
}
225+
139226
/**
140227
* Tests that modifier classes on the first compound selector are preserved
141228
* when state selectors are scoped to the block wrapper.
@@ -835,7 +922,7 @@ public function test_responsive_pseudo_state_generates_media_query_scoped_css()
835922
$actual_stylesheet = wp_style_engine_get_stylesheet_from_context( 'block-supports', array( 'prettify' => false ) );
836923

837924
$this->assertStringContainsString(
838-
'@media (width <= 480px){.' . $matches[0] . ' .wp-block-button__link:hover{background-color:#ff00d0 !important;}}',
925+
'@media (width <= 480px){.' . $matches[0] . ' .wp-block-button__link:hover{background-color:#ff00d0 !important;background-image:unset !important;}}',
839926
$actual_stylesheet
840927
);
841928
}

0 commit comments

Comments
 (0)