From 906e0f21ef95a06ddc164892f4392fe60fcb2f30 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 13 Jan 2026 12:14:59 +0100 Subject: [PATCH] Customize: Preserve CSS cascade for Additional CSS in classic themes. Restores the `$is_block_theme` check that was inadvertently removed in [61473]. This ensures that for classic themes, the Customizer's Additional CSS continues to be printed separately via `wp_custom_css_cb()` at priority 101 in `wp_head`, preserving its position at the end of the `` for highest CSS specificity. For block themes, the Customizer CSS is merged into the global styles stylesheet before the global styles custom CSS, maintaining the intended cascade order. This fixes two issues introduced by the Global Styles lift for classic themes: 1. Live preview in the Customizer not working for Additional CSS changes. 2. Additional CSS losing its cascade advantage due to being buried in the global styles stylesheet. Props westonruter. Fixes #64408. Co-Authored-By: Claude Opus 4.5 --- src/wp-includes/script-loader.php | 58 ++++++++++++++++++------------- tests/phpunit/tests/template.php | 2 ++ 2 files changed, 35 insertions(+), 25 deletions(-) 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',