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

Setting background-image overrides background gradient #60401

Open
susurruses opened this issue Apr 3, 2024 · 7 comments
Open

Setting background-image overrides background gradient #60401

susurruses opened this issue Apr 3, 2024 · 7 comments
Labels
[Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi [Package] Style Engine /packages/style-engine [Type] Bug An existing feature does not function as intended

Comments

@susurruses
Copy link

Description

When editing a block that supports both a Background Gradient and Background Image, these are set as inline styles in such a way that the image overrides the gradient. For example, here's the style attribute for a group block with both a gradient and image:

style="background:linear-gradient(265deg,#D8613C 0%,#F9F9F9 100%);background-image:url('https://example.com/wp-content/uploads/2024/04/image.png');background-size:cover;"

Ideally, this should instead output something like the following:

style="background-image:url('https://example.com/wp-content/uploads/2024/04/image.png'),linear-gradient(265deg,#D8613C 0%,#F9F9F9 100%);background-size:cover;"
(Note the switch to background-image from background, and comma separation between the two background-images.)

The use case for having both a background-image and background gradient is when a partially-transparent image is shown above a gradient, such as putting a pattern or other graphic on top of a gradient. (In theory there could also be use cases of wanting a translucent gradient on top of an image, but that would likely be better served by a Cover block.)

There is already a ticket for switching background to background-image (32787), but that alone won't solve the issue here of needing a single background-image property to contain both the gradient and image.

A work-around is to nest group blocks, setting the gradient on one and the image on the other, but this is clunky and the presence of both background and background-image in the interface implies that both can be added, with no error shown for trying to add both.

Step-by-step reproduction instructions

  1. Create a Group block
  2. Set a background gradient for the group block
  3. Set a background image (e.g., you could try one of these transparent background images)
  4. Save, view the page, and view the source to see a background property for the gradient and background-image for the image.

Screenshots, screen recording, code snippet

No response

Environment info

WordPress 6.5 with TT4 theme

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

@susurruses susurruses added the [Type] Bug An existing feature does not function as intended label Apr 3, 2024
@ramonjd ramonjd added the [Package] Style Engine /packages/style-engine label Apr 3, 2024
@andrewserong andrewserong added the [Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi label Apr 3, 2024
@ramonjd
Copy link
Member

ramonjd commented Apr 3, 2024

This could be done while addressing #32787 I think

Ideally Gutenberg would use background-image for both. And, where there are two, create something like:

background-image: linear-gradient(rgba(0, 0, 255, 0.5), rgba(255, 255, 0, 0.5)),
                  url("../../uploads/dragon.png");

@susurruses
Copy link
Author

Yep, totally! Though this does show that there may be conflicting use-cases, where some people want the gradient on top of the image (e.g., semi-transparent gradient overlay), and some want the image on top of the gradient (e.g., texture over the top of gradient).

Ideally, we'd have a layers interface for backgrounds, so that we could control the stacking order. This could in theory also be extended to support additional layers (multiple background gradients and/or images):

background-stack-order

@ramonjd
Copy link
Member

ramonjd commented Apr 3, 2024

Though this does show that there may be conflicting use-cases, where some people want the gradient on top of the image (e.g., semi-transparent gradient overlay), and some want the image on top of the gradient (e.g., texture over the top of gradient

Good point, thanks for raising it. And also for the helpful mock up 🙇🏻

@ramonjd
Copy link
Member

ramonjd commented Apr 12, 2024

I'm starting some notes about how to approach consolidating color.gradient with background.backgroundImage, not only underneath the same CSS property (background-image), but potentially relocation background properties in the style object tree.

The latter could be optional, but regardless, it'll require a far bit of refactoring and backwards compatibility work.

This is just a 20 min brain dump. I'll come back and add and clean up. Feel free to add your own thoughts!

Consolidating background styles

  1. Switch CSS for color.gradient to use background-image CSS property instead of background
    1. background.backgroundImage also uses background-image so the values will have to be merged behind the scenes. E.g., background-image:url('image.png'),linear-gradient(265deg,#D8613C 0%,#F9F9F9 100%)
    2. Controlling order won't yet be possible. Maybe image first, then gradient to start with pending further iterations.
  2. Migrate style object (theme.json and block supports) (optional but maybe better longer term)
    1. Move gradient to background block supports - color.gradient to background.gradient (or whatever the new property will be called).
    2. Backwards compatibility considerations:
      1. Some posts will have inline styles with color.gradient (background CSS). Existing inline style will still work, but we'll have some style transforms in there to ensure any existing background values are translated to background-image (style engine?)
      2. Existing theme.json and style variation files will have backgrounds set via color.gradient. We should still support these but process them as if they were under background.gradient.
      3. Generating theme.json stylesheets should work as before, but with the gradients using the background-image property instead of background
      4. Theme.json settings would continue to use "color.gradients" arrays. How to ensure that generated preset classes/CSS use background-image and take into account any background images?
      5. block.json supports color.gradients and color.__experimentalDefaultControls.gradients should also trigger support for background.gradient and background.__experimentalDefaultControls.gradient
  3. UI controls (needs design)
    1. Should we move gradient background control sit underneath "Background"?
    2. What about color.background?
    3. Order of gradient and image, should be able to control this
    4. background-image supports multiple images, the design should cater for this as well

@andrewserong
Copy link
Contributor

Nicely summed up @ramonjd, it sure is a complex one! One other potential bit of complexity:

  • If a block has a gradient background in global styles, and then at the individual block level, the user goes to add a background image, should the background image override the global styles gradient, or attempt to merge them together?
  • Related: If a gradient or background image is set for a block in global styles, how does an individual block set the value back to "none" (i.e. clear out a gradient or background image)

I don't think we necessarily need answers to either of those yet, but they were just two questions the sprung to mind while reading the list 🙂

@ramonjd
Copy link
Member

ramonjd commented Apr 14, 2024

If a block has a gradient background in global styles, and then at the individual block level, the user goes to add a background image, should the background image override the global styles gradient, or attempt to merge them together?

Related: If a gradient or background image is set for a block in global styles, how does an individual block set the value back to "none" (i.e. clear out a gradient or background image)

This will be a very interesting UX challenge 😄 Thanks for noting those.

Without thinking one iota, I'd submit that we override as we normally do with other properties, but let's see how the pieces of the puzzle fall together.

@ramonjd
Copy link
Member

ramonjd commented Apr 15, 2024

Another curly one will be how to deal with theme presets applied to blocks/backgrounds.

So if a user applies a gradient preset, and then adds a background image in the editor, or a background image is set in theme.json or elsewhere.

In the following example a preset gradient is set on a Group block, which overrides the background image:

--wp--preset--gradient--gradient-4: linear-gradient(to bottom, #B1C5A4 0%, #F9F9F9 100%);

.has-gradient-4-gradient-background{background: var(--wp--preset--gradient--gradient-4) !important;}
<div class="wp-block-group has-gradient-4-gradient-background has-background has-global-padding is-layout-constrained wp-block-group-is-layout-constrained" style="min-height:162px;background-image:url('http://localhost:8888/wp-content/uploads/2024/04/Westwood-Pizza-newtown-1.jpg');background-size:cover;">
<p>I have a gradient preset background</p>
</div>

I suppose Gutenberg could scan for has-gradient- classes, parse out the preset slug, get the value from theme settings using that slug, and then merge with the inline style background-image.

Also PROPERTIES_METADATA needs to have unique keys. One prep task might be to extend the way it works so that one property can support multiple paths, e.g.,

'background-image' => array(
    array( 'color', 'gradient' ),
    array( 'background', 'backgroundImage' )
),

Not sure.

I think the first step in all this is to migrate color.gradient from background to background-image so at least it's not overwriting other background- CSS properties as described in #32787

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi [Package] Style Engine /packages/style-engine [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

No branches or pull requests

3 participants