diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index ca79bc98a3fa7..84c1732833c7e 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -2495,6 +2495,7 @@ private static function get_block_nodes( $theme_json ) { * Gets the CSS rules for a particular block from theme.json. * * @since 6.1.0 + * @since 6.6.0 Setting a min-height of HTML when root styles have a background gradient or image. * * @param array $block_metadata Metadata about the block to get styles for. * @@ -2506,6 +2507,7 @@ public function get_styles_for_block( $block_metadata ) { $selector = $block_metadata['selector']; $settings = isset( $this->theme_json['settings'] ) ? $this->theme_json['settings'] : array(); $feature_declarations = static::get_feature_declarations_for_node( $block_metadata, $node ); + $is_root_selector = static::ROOT_BLOCK_SELECTOR === $selector; // If there are style variations, generate the declarations for them, including any feature selectors the block may have. $style_variation_declarations = array(); @@ -2588,15 +2590,53 @@ static function ( $pseudo_selector ) use ( $selector ) { $block_rules = ''; /* - * 1. Separate the declarations that use the general selector + * 1. Bespoke declaration modifiers: + * - 'filter': Separate the declarations that use the general selector * from the ones using the duotone selector. + * - 'background|background-image': set the html min-height to 100% + * to ensure the background covers the entire viewport. */ - $declarations_duotone = array(); + $declarations_duotone = array(); + $should_set_root_min_height = false; + foreach ( $declarations as $index => $declaration ) { if ( 'filter' === $declaration['name'] ) { + /* + * 'unset' filters happen when a filter is unset + * in the site-editor UI. Because the 'unset' value + * in the user origin overrides the value in the + * theme origin, we can skip rendering anything + * here as no filter needs to be applied anymore. + * So only add declarations to with values other + * than 'unset'. + */ + if ( 'unset' !== $declaration['value'] ) { + $declarations_duotone[] = $declaration; + } unset( $declarations[ $index ] ); - $declarations_duotone[] = $declaration; } + + if ( $is_root_selector && ( 'background-image' === $declaration['name'] || 'background' === $declaration['name'] ) ) { + $should_set_root_min_height = true; + } + } + + /* + * If root styles has a background-image or a background (gradient) set, + * set the min-height to '100%'. Minus `--wp-admin--admin-bar--height` for logged-in view. + * Setting the CSS rule on the HTML tag ensures background gradients and images behave similarly, + * and matches the behavior of the site editor. + */ + if ( $should_set_root_min_height ) { + $block_rules .= static::to_ruleset( + 'html', + array( + array( + 'name' => 'min-height', + 'value' => 'calc(100% - var(--wp-admin--admin-bar--height, 0px))', + ), + ) + ); } // Update declarations if there are separators with only background color defined. @@ -2614,7 +2654,7 @@ static function ( $pseudo_selector ) use ( $selector ) { // 4. Generate Layout block gap styles. if ( - static::ROOT_BLOCK_SELECTOR !== $selector && + ! $is_root_selector && ! empty( $block_metadata['name'] ) ) { $block_rules .= $this->get_layout_styles( $block_metadata );