diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index 9d5b13426f4ef..b825695c41de3 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -50,6 +50,18 @@ function wp_render_custom_css_support_styles( $parsed_block ) { * and can override global styles. */ wp_register_style( 'wp-block-custom-css', false, array( 'global-styles' ) ); + + // Skip if already enqueued — prevents duplication inside Query Loop. + global $wp_styles; + $existing_inline_styles = $wp_styles->get_data( 'wp-block-custom-css', 'after' ); + if ( is_array( $existing_inline_styles ) ) { + foreach ( $existing_inline_styles as $style ) { + if ( str_contains( $style, $selector ) ) { + return $parsed_block; + } + } + } + wp_add_inline_style( 'wp-block-custom-css', $processed_css ); } diff --git a/tests/phpunit/tests/block-supports/wpRenderCustomCssSupportStyles.php b/tests/phpunit/tests/block-supports/wpRenderCustomCssSupportStyles.php index 0048b379f8f33..bdd47df0520a5 100644 --- a/tests/phpunit/tests/block-supports/wpRenderCustomCssSupportStyles.php +++ b/tests/phpunit/tests/block-supports/wpRenderCustomCssSupportStyles.php @@ -264,4 +264,51 @@ public function data_does_not_add_class_name() { ), ); } + + /** + * Tests that CSS is not duplicated when the same block renders multiple times (e.g. inside a Query Loop). + * + * @ticket 65268 + * + * @covers ::wp_render_custom_css_support_styles + */ + public function test_css_not_duplicated_inside_query_loop() { + $this->test_block_name = 'test/custom-css-query-loop'; + register_block_type( + $this->test_block_name, + array( + 'api_version' => 3, + 'attributes' => array( + 'style' => array( + 'type' => 'object', + ), + ), + 'supports' => array( 'customCSS' => true ), + ) + ); + + $parsed_block = array( + 'blockName' => 'test/custom-css-query-loop', + 'attrs' => array( + 'style' => array( + 'css' => 'color: fuchsia;', + ), + ), + ); + + // Simulate the same block rendering 3 times inside a Query Loop. + wp_render_custom_css_support_styles( $parsed_block ); + wp_render_custom_css_support_styles( $parsed_block ); + wp_render_custom_css_support_styles( $parsed_block ); + + // Get the inline styles registered for wp-block-custom-css. + global $wp_styles; + $inline_css = $wp_styles->get_data( 'wp-block-custom-css', 'after' ); + + // CSS should appear only once, not 3 times. + $this->assertIsArray( $inline_css, 'Inline styles should be registered.' ); + $combined = implode( '', $inline_css ); + $count = substr_count( $combined, 'color: fuchsia' ); + $this->assertSame( 1, $count, 'CSS should only be enqueued once even when block renders multiple times.' ); + } }