Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global styles: force root min-height of 100% for backgrounds #59809

Merged
merged 6 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -2518,6 +2518,7 @@ private static function get_block_nodes( $theme_json, $selectors = array() ) {
* 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.
*
Expand All @@ -2528,6 +2529,7 @@ public function get_styles_for_block( $block_metadata ) {
$use_root_padding = isset( $this->theme_json['settings']['useRootPaddingAwareAlignments'] ) && true === $this->theme_json['settings']['useRootPaddingAwareAlignments'];
$selector = $block_metadata['selector'];
$settings = $this->theme_json['settings'] ?? null;
$is_root_selector = static::ROOT_BLOCK_SELECTOR === $selector;

$feature_declarations = static::get_feature_declarations_for_node( $block_metadata, $node );

Expand Down Expand Up @@ -2613,10 +2615,16 @@ 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'] ) {
/*
Expand All @@ -2633,6 +2641,28 @@ static function ( $pseudo_selector ) use ( $selector ) {
}
unset( $declarations[ $index ] );
}

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',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why on the HTML and not BODY?

  • setting it on the body revealed potential issues, e.g., the background gradient did not always stretch (unless we used 100vh)
  • Also unpredictable margins causing scrolling , e.g., an unstyled H1 at the root of the document in empty theme
  • Settings "styles.dimensions.minHeight" in theme.json would overwrite the value - I suppose this would be fine for theme devs who know what they're doing, but for folks using themes that have "styles.dimensions.minHeight" hardcoded it would mean that backgrounds don't behave as they should, that is, with the background gradient/image filling the window.
  • 'HTML' is also the selector that's being used in the editor to achieve the same effect.

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.
Expand All @@ -2650,7 +2680,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 );
Expand Down
4 changes: 2 additions & 2 deletions phpunit/class-wp-theme-json-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -4802,7 +4802,7 @@ public function test_get_top_level_background_image_styles() {
'backgroundImage' => array(
'url' => 'http://example.org/image.png',
),
'backgroundSize' => 'cover',
'backgroundSize' => 'contain',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
),
Expand Down Expand Up @@ -4835,7 +4835,7 @@ public function test_get_top_level_background_image_styles() {
)
);

$expected_styles = "body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}body{background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: cover;}";
$expected_styles = "body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}body{background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}";
$this->assertSame( $expected_styles, $theme_json->get_stylesheet() );
}

Expand Down
Loading