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

Sticky Position: Fix top position while logged in on mobile #47665

Merged
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
17 changes: 11 additions & 6 deletions lib/block-supports/position.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand All @@ -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[] =
Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 4 additions & 0 deletions packages/block-editor/src/hooks/position.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
19 changes: 19 additions & 0 deletions packages/block-library/src/common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
}
}
4 changes: 2 additions & 2 deletions phpunit/block-supports/position-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ public function data_position_block_support() {
'type' => 'sticky',
'top' => '0px',
),
'expected_wrapper' => '/^<div class="wp-container-\d+">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' => '/^<div class="wp-container-\d+ is-position-sticky">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',
Expand Down