diff --git a/lib/block-supports/position.php b/lib/block-supports/position.php index 8d1436049a7e42..62a51c486362e7 100644 --- a/lib/block-supports/position.php +++ b/lib/block-supports/position.php @@ -61,19 +61,22 @@ function gutenberg_render_position_support( $block_content, $block ) { $selector = ".$class_name"; $position_styles = array(); $position_type = _wp_array_get( $style_attribute, array( 'position', 'type' ), '' ); + $wrapper_classes = array(); if ( in_array( $position_type, $allowed_position_types, true ) ) { - $sides = array( 'top', 'right', 'bottom', 'left' ); + $wrapper_classes[] = $class_name; + $wrapper_classes[] = 'is-position-' . $position_type; + $sides = array( 'top', 'right', 'bottom', 'left' ); foreach ( $sides as $side ) { $side_value = _wp_array_get( $style_attribute, array( 'position', $side ) ); if ( null !== $side_value ) { /* - * For fixed or sticky top positions, - * ensure the value includes an offset for the logged in admin bar. - */ + * For fixed or sticky top positions, + * ensure the value includes an offset for the logged in admin bar. + */ if ( 'top' === $side && ( 'fixed' === $position_type || 'sticky' === $position_type ) @@ -84,7 +87,7 @@ function gutenberg_render_position_support( $block_content, $block ) { } // Ensure current side value also factors in the height of the logged in admin bar. - $side_value = "calc($side_value + var(--wp-admin--admin-bar--height, 0px))"; + $side_value = "calc($side_value + var(--wp-admin--admin-bar--position-offset, 0px))"; } $position_styles[] = @@ -122,7 +125,9 @@ function gutenberg_render_position_support( $block_content, $block ) { // Inject class name to block container markup. $content = new WP_HTML_Tag_Processor( $block_content ); $content->next_tag(); - $content->add_class( $class_name ); + foreach ( $wrapper_classes as $class ) { + $content->add_class( $class ); + } return (string) $content; } diff --git a/packages/block-editor/src/hooks/position.js b/packages/block-editor/src/hooks/position.js index 0da4e78d2bbfca..d2924a84db4397 100644 --- a/packages/block-editor/src/hooks/position.js +++ b/packages/block-editor/src/hooks/position.js @@ -365,6 +365,10 @@ export const withPositionStyles = createHigherOrderComponent( // Attach a `wp-container-` id-based class name. const className = classnames( props?.className, { [ `wp-container-${ id }` ]: allowPositionStyles && !! css, // Only attach a container class if there is generated CSS to be attached. + [ `is-position-${ attributes?.style?.position?.type }` ]: + allowPositionStyles && + !! css && + !! attributes?.style?.position?.type, } ); return ( diff --git a/packages/block-library/src/common.scss b/packages/block-library/src/common.scss index d92f9173cb223c..8d8719b7a24d4b 100644 --- a/packages/block-library/src/common.scss +++ b/packages/block-library/src/common.scss @@ -161,3 +161,22 @@ html :where(img[class*="wp-image-"]) { figure { margin: 0 0 1em 0; } + +// Set the admin bar offset for sticky positioned blocks to the height of the admin bar. +// This allows sticky positioned blocks to be positioned correctly when the admin bar is visible. +html :where(.is-position-sticky) { + /* stylelint-disable length-zero-no-unit */ + --wp-admin--admin-bar--position-offset: var(--wp-admin--admin-bar--height, 0px); // 0px is set explicitly so that it can be used in a calc value. + /* stylelint-enable length-zero-no-unit */ +} + +// To support sticky positioning, reset the admin bar offset to 0px on mobile devices, +// within the scope of the position classname. This is required because the admin bar +// is not fixed to the top on mobile devices, but is fixed on viewports larger than 600px. +@media screen and (max-width: 600px) { + html :where(.is-position-sticky) { + /* stylelint-disable length-zero-no-unit */ + --wp-admin--admin-bar--position-offset: 0px; // 0px is set explicitly so that it can be used in a calc value. + /* stylelint-enable length-zero-no-unit */ + } +} diff --git a/phpunit/block-supports/position-test.php b/phpunit/block-supports/position-test.php index 67bebc0bed5478..c304ffa68e7de5 100644 --- a/phpunit/block-supports/position-test.php +++ b/phpunit/block-supports/position-test.php @@ -131,8 +131,8 @@ public function data_position_block_support() { 'type' => 'sticky', 'top' => '0px', ), - 'expected_wrapper' => '/^
Content<\/div>$/', - 'expected_styles' => '/^.wp-container-\d+' . preg_quote( '{top:calc(0px + var(--wp-admin--admin-bar--height, 0px));position:sticky;z-index:10;}' ) . '$/', + 'expected_wrapper' => '/^
Content<\/div>$/', + 'expected_styles' => '/^.wp-container-\d+' . preg_quote( '{top:calc(0px + var(--wp-admin--admin-bar--position-offset, 0px));position:sticky;z-index:10;}' ) . '$/', ), 'sticky position style is not applied if theme does not support it' => array( 'theme_name' => 'default',