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

Background: add background attachment to top level styles #61382

Merged
merged 9 commits into from
Jul 16, 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
3 changes: 3 additions & 0 deletions backport-changelog/6.7/6991.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
https://github.com/WordPress/wordpress-develop/pull/6991

* https://github.com/WordPress/gutenberg/pull/61382
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ Background styles.
| backgroundPosition | string, object | |
| backgroundRepeat | string, object | |
| backgroundSize | string, object | |
| backgroundAttachment | string, object | |

---

Expand Down
12 changes: 6 additions & 6 deletions lib/block-supports/background.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ function gutenberg_render_background_support( $block_content, $block ) {
return $block_content;
}

$background_styles = array();
$background_styles['backgroundImage'] = $block_attributes['style']['background']['backgroundImage'] ?? null;
$background_styles['backgroundSize'] = $block_attributes['style']['background']['backgroundSize'] ?? null;
$background_styles['backgroundPosition'] = $block_attributes['style']['background']['backgroundPosition'] ?? null;
$background_styles['backgroundRepeat'] = $block_attributes['style']['background']['backgroundRepeat'] ?? null;

$background_styles = array();
$background_styles['backgroundImage'] = $block_attributes['style']['background']['backgroundImage'] ?? null;
$background_styles['backgroundSize'] = $block_attributes['style']['background']['backgroundSize'] ?? null;
$background_styles['backgroundPosition'] = $block_attributes['style']['background']['backgroundPosition'] ?? null;
$background_styles['backgroundRepeat'] = $block_attributes['style']['background']['backgroundRepeat'] ?? null;
$background_styles['backgroundAttachment'] = $block_attributes['style']['background']['backgroundAttachment'] ?? null;
if ( ! empty( $background_styles['backgroundImage'] ) ) {
$background_styles['backgroundSize'] = $background_styles['backgroundSize'] ?? 'cover';
// If the background size is set to `contain` and no position is set, set the position to `center`.
Expand Down
10 changes: 6 additions & 4 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ class WP_Theme_JSON_Gutenberg {
'background-position' => array( 'background', 'backgroundPosition' ),
'background-repeat' => array( 'background', 'backgroundRepeat' ),
'background-size' => array( 'background', 'backgroundSize' ),
'background-attachment' => array( 'background', 'backgroundAttachment' ),
'border-radius' => array( 'border', 'radius' ),
'border-top-left-radius' => array( 'border', 'radius', 'topLeft' ),
'border-top-right-radius' => array( 'border', 'radius', 'topRight' ),
Expand Down Expand Up @@ -503,10 +504,11 @@ class WP_Theme_JSON_Gutenberg {
*/
const VALID_STYLES = array(
'background' => array(
'backgroundImage' => null,
'backgroundPosition' => null,
'backgroundRepeat' => null,
'backgroundSize' => null,
'backgroundImage' => null,
'backgroundAttachment' => null,
'backgroundPosition' => null,
'backgroundRepeat' => null,
'backgroundSize' => null,
),
'border' => array(
'color' => null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,9 @@ function BackgroundSizeControls( {
const positionValue =
style?.background?.backgroundPosition ||
inheritedValue?.background?.backgroundPosition;
const attachmentValue =
style?.background?.backgroundAttachment ||
inheritedValue?.background?.backgroundAttachment;

/*
* An `undefined` value is replaced with any supplied
Expand Down Expand Up @@ -546,8 +549,17 @@ function BackgroundSizeControls( {
)
);

const toggleScrollWithPage = () =>
onChange(
setImmutably(
style,
[ 'background', 'backgroundAttachment' ],
attachmentValue === 'fixed' ? 'scroll' : 'fixed'
)
);

return (
<VStack spacing={ 3 } className="single-column">
<VStack spacing={ 4 } className="single-column">
<FocalPointPicker
__next40pxDefaultSize
__nextHasNoMarginBottom
Expand All @@ -556,6 +568,14 @@ function BackgroundSizeControls( {
value={ backgroundPositionToCoords( positionValue ) }
onChange={ updateBackgroundPosition }
/>
<ToggleControl
Copy link
Member Author

@ramonjd ramonjd Jul 5, 2024

Choose a reason for hiding this comment

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

I've put no thought put into this location or the actual control. Could you tell? 🤣

It does affect the height of the popover, so maybe there's some optimization required.

Elsewhere I've tried using a select dropdown for the size options, and having it site to the side, e.g.,

Screenshot 2024-07-05 at 11 47 45 AM

It's a bit of a control salad 😄

The problem is that translations can and do push out the copy.

I wonder if an accordion or something similar might help to use the space more evenly?

The help text for this toggle could be removed as well.

label={ __( 'Fixed background' ) }
checked={ attachmentValue === 'fixed' }
onChange={ toggleScrollWithPage }
help={ __(
'Whether your image should scroll with the page or stay fixed in place.'
) }
/>
<ToggleGroupControl
size="__unstable-large"
label={ __( 'Size' ) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ const {
FiltersPanel: StylesFiltersPanel,
ImageSettingsPanel,
AdvancedPanel: StylesAdvancedPanel,
useGlobalStyleLinks,
} = unlock( blockEditorPrivateApis );

function ScreenBlock( { name, variation } ) {
Expand All @@ -103,6 +104,7 @@ function ScreenBlock( { name, variation } ) {
const [ rawSettings, setSettings ] = useGlobalSetting( '', name );
const settings = useSettingsForBlockElement( rawSettings, name );
const blockType = getBlockType( name );
const _links = useGlobalStyleLinks();

// Only allow `blockGap` support if serialization has not been skipped, to be sure global spacing can be applied.
if (
Expand Down Expand Up @@ -311,10 +313,7 @@ function ScreenBlock( { name, variation } ) {
onChange={ setStyle }
settings={ settings }
defaultValues={ BACKGROUND_BLOCK_DEFAULT_VALUES }
defaultControls={
blockType?.supports?.background
?.__experimentalDefaultControls
}
themeFileURIs={ _links?.[ 'wp:theme-file' ] }
/>
) }

Expand Down
14 changes: 10 additions & 4 deletions packages/style-engine/class-wp-style-engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,31 +42,37 @@ final class WP_Style_Engine {
*/
const BLOCK_STYLE_DEFINITIONS_METADATA = array(
'background' => array(
'backgroundImage' => array(
'backgroundImage' => array(
'property_keys' => array(
'default' => 'background-image',
),
'value_func' => array( self::class, 'get_url_or_value_css_declaration' ),
'path' => array( 'background', 'backgroundImage' ),
),
'backgroundPosition' => array(
'backgroundPosition' => array(
'property_keys' => array(
'default' => 'background-position',
),
'path' => array( 'background', 'backgroundPosition' ),
),
'backgroundRepeat' => array(
'backgroundRepeat' => array(
'property_keys' => array(
'default' => 'background-repeat',
),
'path' => array( 'background', 'backgroundRepeat' ),
),
'backgroundSize' => array(
'backgroundSize' => array(
'property_keys' => array(
'default' => 'background-size',
),
'path' => array( 'background', 'backgroundSize' ),
),
'backgroundAttachment' => array(
'property_keys' => array(
'default' => 'background-attachment',
),
'path' => array( 'background', 'backgroundAttachment' ),
),
),
'color' => array(
'text' => array(
Expand Down
13 changes: 13 additions & 0 deletions packages/style-engine/src/styles/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,22 @@ const backgroundSize = {
},
};

const backgroundAttachment = {
name: 'backgroundAttachment',
generate: ( style: Style, options: StyleOptions ) => {
return generateRule(
style,
options,
[ 'background', 'backgroundAttachment' ],
'backgroundAttachment'
);
},
};

export default [
backgroundImage,
backgroundPosition,
backgroundRepeat,
backgroundSize,
backgroundAttachment,
];
6 changes: 6 additions & 0 deletions packages/style-engine/src/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ describe( 'getCSSRules', () => {
backgroundPosition: '50% 50%',
backgroundRepeat: 'no-repeat',
backgroundSize: '300px',
backgroundAttachment: 'fixed',
},
color: {
text: '#dddddd',
Expand Down Expand Up @@ -399,6 +400,11 @@ describe( 'getCSSRules', () => {
key: 'backgroundSize',
value: '300px',
},
{
selector: '.some-selector',
key: 'backgroundAttachment',
value: 'fixed',
},
] );
} );

Expand Down
11 changes: 6 additions & 5 deletions phpunit/block-supports/background-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,21 +149,22 @@ public function data_background_block_support() {
'expected_wrapper' => '<div class="has-background" style="background-image:url(&#039;https://example.com/image.jpg&#039;);background-size:cover;">Content</div>',
'wrapper' => '<div>Content</div>',
),
'background image style with contain, position, and repeat is applied' => array(
'background image style with contain, position, attachment, and repeat is applied' => array(
'theme_name' => 'block-theme-child-with-fluid-typography',
'block_name' => 'test/background-rules-are-output',
'background_settings' => array(
'backgroundImage' => true,
),
'background_style' => array(
'backgroundImage' => array(
'backgroundImage' => array(
'url' => 'https://example.com/image.jpg',
'source' => 'file',
),
'backgroundRepeat' => 'no-repeat',
'backgroundSize' => 'contain',
'backgroundRepeat' => 'no-repeat',
'backgroundSize' => 'contain',
'backgroundAttachment' => 'fixed',
),
'expected_wrapper' => '<div class="has-background" style="background-image:url(&#039;https://example.com/image.jpg&#039;);background-position:center;background-repeat:no-repeat;background-size:contain;">Content</div>',
'expected_wrapper' => '<div class="has-background" style="background-image:url(&#039;https://example.com/image.jpg&#039;);background-position:center;background-repeat:no-repeat;background-size:contain;background-attachment:fixed;">Content</div>',
'wrapper' => '<div>Content</div>',
),
'background image style is appended if a style attribute already exists' => array(
Expand Down
33 changes: 18 additions & 15 deletions phpunit/class-wp-theme-json-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -4765,12 +4765,13 @@ public function test_get_top_level_background_image_styles() {
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
'styles' => array(
'background' => array(
'backgroundImage' => array(
'backgroundImage' => array(
'url' => 'http://example.org/image.png',
),
'backgroundSize' => 'contain',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
'backgroundSize' => 'contain',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
'backgroundAttachment' => 'fixed',
),
),
)
Expand All @@ -4781,24 +4782,25 @@ public function test_get_top_level_background_image_styles() {
'selector' => 'body',
);

$expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}";
$expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;background-attachment: fixed;}";
$this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_styles_for_block()" with top-level background styles do not match expectations' );

$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
'styles' => array(
'background' => array(
'backgroundImage' => "url('http://example.org/image.png')",
'backgroundSize' => 'contain',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
'backgroundImage' => "url('http://example.org/image.png')",
'backgroundSize' => 'contain',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
'backgroundAttachment' => 'fixed',
),
),
)
);

$expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}";
$expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;background-attachment: fixed;}";
$this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_styles_for_block()" with top-level background image as string type do not match expectations' );
}

Expand All @@ -4810,10 +4812,11 @@ public function test_get_block_background_image_styles() {
'blocks' => array(
'core/group' => array(
'background' => array(
'backgroundImage' => "url('http://example.org/group.png')",
'backgroundSize' => 'cover',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
'backgroundImage' => "url('http://example.org/group.png')",
'backgroundSize' => 'cover',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
'backgroundAttachment' => 'fixed',
),
),
'core/quote' => array(
Expand Down Expand Up @@ -4852,7 +4855,7 @@ public function test_get_block_background_image_styles() {
),
);

$group_styles = ":root :where(.wp-block-group){background-image: url('http://example.org/group.png');background-position: center center;background-repeat: no-repeat;background-size: cover;}";
$group_styles = ":root :where(.wp-block-group){background-image: url('http://example.org/group.png');background-position: center center;background-repeat: no-repeat;background-size: cover;background-attachment: fixed;}";
$this->assertSame( $group_styles, $theme_json->get_styles_for_block( $group_node ), 'Styles returned from "::get_styles_for_block()" with block-level background styles as string type do not match expectations' );
}

Expand Down
20 changes: 11 additions & 9 deletions phpunit/style-engine/style-engine-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -506,22 +506,24 @@ public function data_wp_style_engine_get_styles() {
'inline_background_image_url_with_background_size' => array(
'block_styles' => array(
'background' => array(
'backgroundImage' => array(
'backgroundImage' => array(
'url' => 'https://example.com/image.jpg',
),
'backgroundPosition' => 'center',
'backgroundRepeat' => 'no-repeat',
'backgroundSize' => 'cover',
'backgroundPosition' => 'center',
'backgroundRepeat' => 'no-repeat',
'backgroundSize' => 'cover',
'backgroundAttachment' => 'fixed',
),
),
'options' => array(),
'expected_output' => array(
'css' => "background-image:url('https://example.com/image.jpg');background-position:center;background-repeat:no-repeat;background-size:cover;",
'css' => "background-image:url('https://example.com/image.jpg');background-position:center;background-repeat:no-repeat;background-size:cover;background-attachment:fixed;",
'declarations' => array(
'background-image' => "url('https://example.com/image.jpg')",
'background-position' => 'center',
'background-repeat' => 'no-repeat',
'background-size' => 'cover',
'background-image' => "url('https://example.com/image.jpg')",
'background-position' => 'center',
'background-repeat' => 'no-repeat',
'background-size' => 'cover',
'background-attachment' => 'fixed',
),
),
),
Expand Down
11 changes: 11 additions & 0 deletions schemas/json/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,17 @@
"$ref": "#/definitions/refComplete"
}
]
},
"backgroundAttachment": {
"description": "Sets the `background-attachment` CSS property.",
"oneOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/refComplete"
}
]
}
},
"additionalProperties": false
Expand Down
Loading