Skip to content

Commit

Permalink
Styles: Level global styles specificity at 0-1-0
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw committed May 29, 2024
1 parent 48d8aef commit 715ab02
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 92 deletions.
18 changes: 9 additions & 9 deletions src/wp-includes/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ function wp_get_layout_definitions() {
),
'spacingStyles' => array(
array(
'selector' => ' > :first-child:first-child',
'selector' => ' > :first-child',
'rules' => array(
'margin-block-start' => '0',
),
),
array(
'selector' => ' > :last-child:last-child',
'selector' => ' > :last-child',
'rules' => array(
'margin-block-end' => '0',
),
Expand Down Expand Up @@ -116,13 +116,13 @@ function wp_get_layout_definitions() {
),
'spacingStyles' => array(
array(
'selector' => ' > :first-child:first-child',
'selector' => ' > :first-child',
'rules' => array(
'margin-block-start' => '0',
),
),
array(
'selector' => ' > :last-child:last-child',
'selector' => ' > :last-child',
'rules' => array(
'margin-block-end' => '0',
),
Expand Down Expand Up @@ -150,7 +150,7 @@ function wp_get_layout_definitions() {
),
),
array(
'selector' => ' > *',
'selector' => ' > :is(*, div)', // :is(*, div) instead of just * increases the specificity by 001.
'rules' => array(
'margin' => '0',
),
Expand All @@ -172,7 +172,7 @@ function wp_get_layout_definitions() {
'displayMode' => 'grid',
'baseStyles' => array(
array(
'selector' => ' > *',
'selector' => ' > :is(*, div)', // :is(*, div) instead of just * increases the specificity by 001.
'rules' => array(
'margin' => '0',
),
Expand Down Expand Up @@ -261,7 +261,7 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false
),
),
array(
'selector' => "$selector$selector > * + *",
'selector' => "$selector > * + *",
'declarations' => array(
'margin-block-start' => $gap_value,
'margin-block-end' => '0',
Expand Down Expand Up @@ -370,7 +370,7 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false
),
),
array(
'selector' => "$selector$selector > * + *",
'selector' => "$selector > * + *",
'declarations' => array(
'margin-block-start' => $gap_value,
'margin-block-end' => '0',
Expand Down Expand Up @@ -795,7 +795,7 @@ function wp_render_layout_support_flag( $block_content, $block ) {
$has_block_gap_support = isset( $block_gap );

$style = wp_get_layout_style(
".$container_class.$container_class",
".$container_class",
$used_layout,
$has_block_gap_support,
$gap_value,
Expand Down
25 changes: 12 additions & 13 deletions src/wp-includes/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,7 @@ protected function process_blocks_custom_css( $css, $selector ) {
$is_root_css = ( ! str_contains( $part, '{' ) );
if ( $is_root_css ) {
// If the part doesn't contain braces, it applies to the root level.
$processed_css .= trim( $selector ) . '{' . trim( $part ) . '}';
$processed_css .= ':root :where(' . trim( $selector ) . '){' . trim( $part ) . '}';
} else {
// If the part contains braces, it's a nested CSS rule.
$part = explode( '{', str_replace( '}', '', $part ) );
Expand All @@ -1292,8 +1292,8 @@ protected function process_blocks_custom_css( $css, $selector ) {
$part_selector = str_starts_with( $nested_selector, ' ' )
? static::scope_selector( $selector, $nested_selector )
: static::append_to_selector( $selector, $nested_selector );
$processed_css .= $part_selector . '{' . trim( $css_value ) . '}';
}
$final_selector = ":root :where($part_selector)";
$processed_css .= $final_selector . '{' . trim( $css_value ) . '}';}
}
return $processed_css;
}
Expand Down Expand Up @@ -1440,7 +1440,7 @@ protected function get_layout_styles( $block_metadata, $types = array() ) {
$has_fallback_gap_support = ! $has_block_gap_support; // This setting isn't useful yet: it exists as a placeholder for a future explicit fallback gap styles support.
$node = _wp_array_get( $this->theme_json, $block_metadata['path'], array() );
$layout_definitions = wp_get_layout_definitions();
$layout_selector_pattern = '/^[a-zA-Z0-9\-\.\ *+>:\(\)]*$/'; // Allow alphanumeric classnames, spaces, wildcard, sibling, child combinator and pseudo class selectors.
$layout_selector_pattern = '/^[a-zA-Z0-9\-\.\,\ *+>:\(\)]*$/'; // Allow alphanumeric classnames, spaces, wildcard, sibling, child combinator and pseudo class selectors.

/*
* Gap styles will only be output if the theme has block gap support, or supports a fallback gap.
Expand Down Expand Up @@ -1515,7 +1515,7 @@ protected function get_layout_styles( $block_metadata, $types = array() ) {
$spacing_rule['selector']
);
} else {
$format = static::ROOT_BLOCK_SELECTOR === $selector ? ':where(%s .%s) %s' : '%s-%s%s';
$format = static::ROOT_BLOCK_SELECTOR === $selector ? '.%2$s %3$s' : '%1$s-%2$s %3$s';
$layout_selector = sprintf(
$format,
$selector,
Expand Down Expand Up @@ -1599,8 +1599,7 @@ protected function get_layout_styles( $block_metadata, $types = array() ) {
}

$layout_selector = sprintf(
'%s .%s%s',
$selector,
'.%s%s',
$class_name,
$base_style_rule['selector']
);
Expand Down Expand Up @@ -2656,7 +2655,7 @@ static function ( $pseudo_selector ) use ( $selector ) {
}

// 2. Generate and append the rules that use the general selector.
$block_rules .= static::to_ruleset( $selector, $declarations );
$block_rules .= static::to_ruleset( ":root :where($selector)", $declarations );

// 3. Generate and append the rules that use the duotone selector.
if ( isset( $block_metadata['duotone'] ) && ! empty( $declarations_duotone ) ) {
Expand All @@ -2673,12 +2672,12 @@ static function ( $pseudo_selector ) use ( $selector ) {

// 5. Generate and append the feature level rulesets.
foreach ( $feature_declarations as $feature_selector => $individual_feature_declarations ) {
$block_rules .= static::to_ruleset( $feature_selector, $individual_feature_declarations );
$block_rules .= static::to_ruleset( ":root :where($feature_selector)", $individual_feature_declarations );
}

// 6. Generate and append the style variation rulesets.
foreach ( $style_variation_declarations as $style_variation_selector => $individual_style_variation_declarations ) {
$block_rules .= static::to_ruleset( $style_variation_selector, $individual_style_variation_declarations );
$block_rules .= static::to_ruleset( ":root :where($style_variation_selector)", $individual_style_variation_declarations );
}

return $block_rules;
Expand Down Expand Up @@ -2720,7 +2719,7 @@ public function get_root_layout_rules( $selector, $block_metadata ) {
* user-generated values take precedence in the CSS cascade.
* @link https://github.com/WordPress/gutenberg/issues/36147.
*/
$css .= 'body { margin: 0; }';
$css .= ':where(body) { margin: 0; }';

if ( $use_root_padding ) {
// Top and bottom padding are applied to the outer block container.
Expand All @@ -2743,8 +2742,8 @@ public function get_root_layout_rules( $selector, $block_metadata ) {
if ( isset( $this->theme_json['settings']['spacing']['blockGap'] ) ) {
$block_gap_value = static::get_property_value( $this->theme_json, array( 'styles', 'spacing', 'blockGap' ) );
$css .= ":where(.wp-site-blocks) > * { margin-block-start: $block_gap_value; margin-block-end: 0; }";
$css .= ':where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }';
$css .= ':where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }';
$css .= ':where(.wp-site-blocks) > :first-child { margin-block-start: 0; }';
$css .= ':where(.wp-site-blocks) > :last-child { margin-block-end: 0; }';

// For backwards compatibility, ensure the legacy block gap CSS variable is still available.
$css .= static::ROOT_CSS_PROPERTIES_SELECTOR . " { --wp--style--block-gap: $block_gap_value; }";
Expand Down
31 changes: 25 additions & 6 deletions tests/phpunit/tests/block-supports/wpGetLayoutStyle.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public function data_wp_get_layout_style() {
'has_block_gap_support' => true,
'gap_value' => '1em',
),
'expected_output' => '.wp-layout > *{margin-block-start:0;margin-block-end:0;}.wp-layout.wp-layout > * + *{margin-block-start:1em;margin-block-end:0;}',
'expected_output' => '.wp-layout > *{margin-block-start:0;margin-block-end:0;}.wp-layout > * + *{margin-block-start:1em;margin-block-end:0;}',
),
'skip serialization should return empty value' => array(
'args' => array(
Expand All @@ -89,7 +89,7 @@ public function data_wp_get_layout_style() {
'has_block_gap_support' => true,
'gap_value' => array( 'top' => '1em' ),
),
'expected_output' => '.wp-layout > *{margin-block-start:0;margin-block-end:0;}.wp-layout.wp-layout > * + *{margin-block-start:1em;margin-block-end:0;}',
'expected_output' => '.wp-layout > *{margin-block-start:0;margin-block-end:0;}.wp-layout > * + *{margin-block-start:1em;margin-block-end:0;}',
),
'constrained layout with sizes' => array(
'args' => array(
Expand Down Expand Up @@ -128,7 +128,7 @@ public function data_wp_get_layout_style() {
'has_block_gap_support' => true,
'gap_value' => '2.5rem',
),
'expected_output' => '.wp-layout > *{margin-block-start:0;margin-block-end:0;}.wp-layout.wp-layout > * + *{margin-block-start:2.5rem;margin-block-end:0;}',
'expected_output' => '.wp-layout > *{margin-block-start:0;margin-block-end:0;}.wp-layout > * + *{margin-block-start:2.5rem;margin-block-end:0;}',
),
'constrained layout with axial block gap support' => array(
'args' => array(
Expand All @@ -139,7 +139,7 @@ public function data_wp_get_layout_style() {
'has_block_gap_support' => true,
'gap_value' => array( 'top' => '2.5rem' ),
),
'expected_output' => '.wp-layout > *{margin-block-start:0;margin-block-end:0;}.wp-layout.wp-layout > * + *{margin-block-start:2.5rem;margin-block-end:0;}',
'expected_output' => '.wp-layout > *{margin-block-start:0;margin-block-end:0;}.wp-layout > * + *{margin-block-start:2.5rem;margin-block-end:0;}',
),
'constrained layout with block gap support and spacing preset' => array(
'args' => array(
Expand All @@ -150,7 +150,7 @@ public function data_wp_get_layout_style() {
'has_block_gap_support' => true,
'gap_value' => 'var:preset|spacing|50',
),
'expected_output' => '.wp-layout > *{margin-block-start:0;margin-block-end:0;}.wp-layout.wp-layout > * + *{margin-block-start:var(--wp--preset--spacing--50);margin-block-end:0;}',
'expected_output' => '.wp-layout > *{margin-block-start:0;margin-block-end:0;}.wp-layout > * + *{margin-block-start:var(--wp--preset--spacing--50);margin-block-end:0;}',
),
'flex layout with no args should return empty value' => array(
'args' => array(
Expand Down Expand Up @@ -248,6 +248,25 @@ public function data_wp_get_layout_style() {
),
'expected_output' => '.wp-layout{flex-wrap:nowrap;flex-direction:column;align-items:flex-start;justify-content:flex-end;}',
),
'default grid layout' => array(
'args' => array(
'selector' => '.wp-layout',
'layout' => array(
'type' => 'grid',
),
),
'expected_output' => '.wp-layout{grid-template-columns:repeat(auto-fill, minmax(min(12rem, 100%), 1fr));container-type:inline-size;}',
),
'grid layout with columnCount' => array(
'args' => array(
'selector' => '.wp-layout',
'layout' => array(
'type' => 'grid',
'columnCount' => 3,
),
),
'expected_output' => '.wp-layout{grid-template-columns:repeat(3, minmax(0, 1fr));}',
),
'default layout with blockGap to verify converting gap value into valid CSS' => array(
'args' => array(
'selector' => '.wp-block-group.wp-container-6',
Expand All @@ -260,7 +279,7 @@ public function data_wp_get_layout_style() {
'blockGap' => 'var(--wp--preset--spacing--70)',
),
),
'expected_output' => '.wp-block-group.wp-container-6 > *{margin-block-start:0;margin-block-end:0;}.wp-block-group.wp-container-6.wp-block-group.wp-container-6 > * + *{margin-block-start:var(--wp--preset--spacing--70);margin-block-end:0;}',
'expected_output' => '.wp-block-group.wp-container-6 > *{margin-block-start:0;margin-block-end:0;}.wp-block-group.wp-container-6 > * + *{margin-block-start:var(--wp--preset--spacing--70);margin-block-end:0;}',
),
);
}
Expand Down
18 changes: 9 additions & 9 deletions tests/phpunit/tests/theme/wpAddGlobalStylesForBlocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function test_third_party_blocks_inline_styles_not_register_to_global_sty
wp_add_global_styles_for_blocks();

$this->assertNotContains(
'.wp-block-my-third-party-block{background-color: hotpink;}',
':root :where(.wp-block-my-third-party-block){background-color: hotpink;}',
$this->get_global_styles()
);
}
Expand All @@ -59,15 +59,15 @@ public function test_third_party_blocks_inline_styles_get_registered_to_global_s
wp_register_style( 'global-styles', false, array(), true, true );

$this->assertNotContains(
'.wp-block-my-third-party-block{background-color: hotpink;}',
':root :where(.wp-block-my-third-party-block){background-color: hotpink;}',
$this->get_global_styles(),
'Third party block inline style should not be registered before running wp_add_global_styles_for_blocks()'
);

wp_add_global_styles_for_blocks();

$this->assertContains(
'.wp-block-my-third-party-block{background-color: hotpink;}',
':root :where(.wp-block-my-third-party-block){background-color: hotpink;}',
$this->get_global_styles(),
'Third party block inline style should be registered after running wp_add_global_styles_for_blocks()'
);
Expand All @@ -83,15 +83,15 @@ public function test_third_party_blocks_inline_styles_get_registered_to_global_s
wp_register_style( 'global-styles', false, array(), true, true );

$this->assertNotContains(
'.wp-block-my-third-party-block{background-color: hotpink;}',
':root :where(.wp-block-my-third-party-block){background-color: hotpink;}',
$this->get_global_styles(),
'Third party block inline style should not be registered before running wp_add_global_styles_for_blocks()'
);

wp_add_global_styles_for_blocks();

$this->assertContains(
'.wp-block-my-third-party-block{background-color: hotpink;}',
':root :where(.wp-block-my-third-party-block){background-color: hotpink;}',
$this->get_global_styles(),
'Third party block inline style should be registered after running wp_add_global_styles_for_blocks()'
);
Expand All @@ -111,7 +111,7 @@ public function test_third_party_blocks_inline_styles_get_rendered_when_per_bloc
$actual = get_echo( 'wp_print_styles' );

$this->assertStringContainsString(
'.wp-block-my-third-party-block{background-color: hotpink;}',
':root :where(.wp-block-my-third-party-block){background-color: hotpink;}',
$actual,
'Third party block inline style should render'
);
Expand All @@ -133,7 +133,7 @@ public function test_blocks_inline_styles_get_rendered() {
$actual = get_echo( 'wp_print_styles' );

$this->assertStringContainsString(
'.wp-block-my-third-party-block{background-color: hotpink;}',
':root :where(.wp-block-my-third-party-block){background-color: hotpink;}',
$actual,
'Third party block inline style should render'
);
Expand All @@ -158,7 +158,7 @@ public function test_third_party_blocks_inline_styles_for_elements_get_rendered_
$actual = get_echo( 'wp_print_styles' );

$this->assertStringContainsString(
'.wp-block-my-third-party-block cite{color: white;}',
':root :where(.wp-block-my-third-party-block cite){color: white;}',
$actual
);
}
Expand All @@ -174,7 +174,7 @@ public function test_third_party_blocks_inline_styles_for_elements_get_rendered(
$actual = get_echo( 'wp_print_styles' );

$this->assertStringContainsString(
'.wp-block-my-third-party-block cite{color: white;}',
':root :where(.wp-block-my-third-party-block cite){color: white;}',
$actual
);
}
Expand Down
Loading

0 comments on commit 715ab02

Please sign in to comment.