From 523a4deb689ae7d90bf277ee3d28bf02461ae466 Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Thu, 2 Feb 2023 13:35:00 +1100 Subject: [PATCH 1/6] Sticky Position: Fix top position while logged in on mobile --- lib/block-supports/position.php | 13 +++++++++---- packages/block-library/src/group/style.scss | 11 +++++++++++ phpunit/block-supports/position-test.php | 2 +- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/block-supports/position.php b/lib/block-supports/position.php index 8d1436049a7e42..fd1f4aee885a88 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 ) ) { + $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 ) @@ -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-library/src/group/style.scss b/packages/block-library/src/group/style.scss index 3457a12adb6221..fc7436d64eebeb 100644 --- a/packages/block-library/src/group/style.scss +++ b/packages/block-library/src/group/style.scss @@ -2,3 +2,14 @@ // This block has customizable padding, border-box makes that more predictable. box-sizing: border-box; } + +// To support sticky positioning, reset the admin bar height to 0px on mobile devices. +// This is required because the admin bar is not fixed to the top on mobile devices, +// but is on viewports larger than 600px. +@media screen and (max-width: 600px) { + .wp-block-group.is-position-sticky { + /* stylelint-disable length-zero-no-unit */ + --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 */ + } +} diff --git a/phpunit/block-supports/position-test.php b/phpunit/block-supports/position-test.php index 67bebc0bed5478..dd06e412801b7a 100644 --- a/phpunit/block-supports/position-test.php +++ b/phpunit/block-supports/position-test.php @@ -131,7 +131,7 @@ public function data_position_block_support() { 'type' => 'sticky', 'top' => '0px', ), - 'expected_wrapper' => '/^
Content<\/div>$/', + '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;}' ) . '$/', ), 'sticky position style is not applied if theme does not support it' => array( From 4081b4f9759dbef5397b7f4e034c4ff1ef38fcf3 Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Thu, 2 Feb 2023 14:20:32 +1100 Subject: [PATCH 2/6] Clarify comment --- packages/block-library/src/group/style.scss | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/group/style.scss b/packages/block-library/src/group/style.scss index fc7436d64eebeb..bb0846fb0cf424 100644 --- a/packages/block-library/src/group/style.scss +++ b/packages/block-library/src/group/style.scss @@ -3,9 +3,10 @@ box-sizing: border-box; } -// To support sticky positioning, reset the admin bar height to 0px on mobile devices. +// To support sticky positioning, reset the admin bar CSS variable height +// to 0px on mobile devices, within the scope of the group block and position classname. // This is required because the admin bar is not fixed to the top on mobile devices, -// but is on viewports larger than 600px. +// but is fixed on viewports larger than 600px. @media screen and (max-width: 600px) { .wp-block-group.is-position-sticky { /* stylelint-disable length-zero-no-unit */ From 82d04e2e3de7c2adb614c795b5f86de7128b2dcc Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Thu, 2 Feb 2023 14:27:36 +1100 Subject: [PATCH 3/6] Ensure classname is output in editor, too --- packages/block-editor/src/hooks/position.js | 4 ++++ 1 file changed, 4 insertions(+) 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 ( From ca318c09d6c74d4fc1eeaad878f98ccc4a9e2eba Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Thu, 2 Feb 2023 14:41:55 +1100 Subject: [PATCH 4/6] Fix linting issue --- lib/block-supports/position.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/block-supports/position.php b/lib/block-supports/position.php index fd1f4aee885a88..feb7e885cdbcc1 100644 --- a/lib/block-supports/position.php +++ b/lib/block-supports/position.php @@ -68,7 +68,7 @@ function gutenberg_render_position_support( $block_content, $block ) { ) { $wrapper_classes[] = $class_name; $wrapper_classes[] = 'is-position-' . $position_type; - $sides = array( 'top', 'right', 'bottom', 'left' ); + $sides = array( 'top', 'right', 'bottom', 'left' ); foreach ( $sides as $side ) { $side_value = _wp_array_get( $style_attribute, array( 'position', $side ) ); From 6f72dd092d9204f86a154712ffb4c16de8d000bc Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Thu, 2 Feb 2023 16:27:45 +1100 Subject: [PATCH 5/6] Move CSS to common.scss, decouple from Group block --- lib/block-supports/position.php | 2 +- packages/block-library/src/common.scss | 19 +++++++++++++++++++ packages/block-library/src/group/style.scss | 12 ------------ phpunit/block-supports/position-test.php | 2 +- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/lib/block-supports/position.php b/lib/block-supports/position.php index feb7e885cdbcc1..62a51c486362e7 100644 --- a/lib/block-supports/position.php +++ b/lib/block-supports/position.php @@ -87,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[] = diff --git a/packages/block-library/src/common.scss b/packages/block-library/src/common.scss index d92f9173cb223c..7b358aee434a93 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) { + .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/packages/block-library/src/group/style.scss b/packages/block-library/src/group/style.scss index bb0846fb0cf424..3457a12adb6221 100644 --- a/packages/block-library/src/group/style.scss +++ b/packages/block-library/src/group/style.scss @@ -2,15 +2,3 @@ // This block has customizable padding, border-box makes that more predictable. box-sizing: border-box; } - -// To support sticky positioning, reset the admin bar CSS variable height -// to 0px on mobile devices, within the scope of the group block and 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) { - .wp-block-group.is-position-sticky { - /* stylelint-disable length-zero-no-unit */ - --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 */ - } -} diff --git a/phpunit/block-supports/position-test.php b/phpunit/block-supports/position-test.php index dd06e412801b7a..c304ffa68e7de5 100644 --- a/phpunit/block-supports/position-test.php +++ b/phpunit/block-supports/position-test.php @@ -132,7 +132,7 @@ public function data_position_block_support() { '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_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', From 52bd2b342d63d323683f8f34a0c42c0c37875fcb Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Thu, 2 Feb 2023 17:11:11 +1100 Subject: [PATCH 6/6] Use same selector inside the media query --- packages/block-library/src/common.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/common.scss b/packages/block-library/src/common.scss index 7b358aee434a93..8d8719b7a24d4b 100644 --- a/packages/block-library/src/common.scss +++ b/packages/block-library/src/common.scss @@ -174,7 +174,7 @@ html :where(.is-position-sticky) { // 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) { - .is-position-sticky { + 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 */