diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 8cd3301ff6fdd..366f8f93667e7 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -2515,35 +2515,43 @@ function wp_enqueue_global_styles() { $stylesheet = wp_get_global_stylesheet(); /* - * Dequeue the Customizer's custom CSS - * and add it before the global styles custom CSS. + * For block themes, merge Customizer's custom CSS into the global styles stylesheet + * before the global styles custom CSS, ensuring proper cascade order. + * For classic themes, let the Customizer CSS print separately via wp_custom_css_cb() + * at priority 101 in wp_head, preserving its position at the end of the . */ - remove_action( 'wp_head', 'wp_custom_css_cb', 101 ); + if ( $is_block_theme ) { + /* + * Dequeue the Customizer's custom CSS + * and add it before the global styles custom CSS. + */ + remove_action( 'wp_head', 'wp_custom_css_cb', 101 ); - /* - * Get the custom CSS from the Customizer and add it to the global stylesheet. - * Always do this in Customizer preview for the sake of live preview since it be empty. - */ - $custom_css = trim( wp_get_custom_css() ); - if ( $custom_css || is_customize_preview() ) { - if ( is_customize_preview() ) { - /* - * When in the Customizer preview, wrap the Custom CSS in milestone comments to allow customize-preview.js - * to locate the CSS to replace for live previewing. Make sure that the milestone comments are omitted from - * the stored Custom CSS if by chance someone tried to add them, which would be highly unlikely, but it - * would break live previewing. - */ - $before_milestone = '/*BEGIN_CUSTOMIZER_CUSTOM_CSS*/'; - $after_milestone = '/*END_CUSTOMIZER_CUSTOM_CSS*/'; - $custom_css = str_replace( array( $before_milestone, $after_milestone ), '', $custom_css ); - $custom_css = $before_milestone . "\n" . $custom_css . "\n" . $after_milestone; + /* + * Get the custom CSS from the Customizer and add it to the global stylesheet. + * Always do this in Customizer preview for the sake of live preview since it be empty. + */ + $custom_css = trim( wp_get_custom_css() ); + if ( $custom_css || is_customize_preview() ) { + if ( is_customize_preview() ) { + /* + * When in the Customizer preview, wrap the Custom CSS in milestone comments to allow customize-preview.js + * to locate the CSS to replace for live previewing. Make sure that the milestone comments are omitted from + * the stored Custom CSS if by chance someone tried to add them, which would be highly unlikely, but it + * would break live previewing. + */ + $before_milestone = '/*BEGIN_CUSTOMIZER_CUSTOM_CSS*/'; + $after_milestone = '/*END_CUSTOMIZER_CUSTOM_CSS*/'; + $custom_css = str_replace( array( $before_milestone, $after_milestone ), '', $custom_css ); + $custom_css = $before_milestone . "\n" . $custom_css . "\n" . $after_milestone; + } + $custom_css = "\n" . $custom_css; } - $custom_css = "\n" . $custom_css; - } - $stylesheet .= $custom_css; + $stylesheet .= $custom_css; - // Add the global styles custom CSS at the end. - $stylesheet .= wp_get_global_stylesheet( array( 'custom-css' ) ); + // Add the global styles custom CSS at the end. + $stylesheet .= wp_get_global_stylesheet( array( 'custom-css' ) ); + } if ( empty( $stylesheet ) ) { return; diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index 6c6f0fcd33aba..dacc69fba6330 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1561,6 +1561,7 @@ static function () { 'global-styles-inline-css', 'normal-css', 'normal-inline-css', + 'wp-custom-css', ), 'BODY' => array( 'late-css', @@ -1622,6 +1623,7 @@ function (): void { 'global-styles-inline-css', 'normal-css', 'normal-inline-css', + 'wp-custom-css', ), 'BODY' => array( 'late-css',