WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.16k stars 4.05k forks source link

Block Supports: Allow themes to set styles when serialization is skipped #32417

Open stacimc opened 3 years ago

stacimc commented 3 years ago

I'd like a flexible way to support setting specific styles via theme.json that do not target the top-level of the block: ie, block supports with __experimentalSkipSerialization enabled. It is currently difficult to do this without affecting all styles for the block. Here's an example:

32416 adds the color block support to the Search block, and enables __experimentalSkipSerialization so that the color selections can be applied to just the Search button rather than at the block's top level:

Screen Shot 2021-06-02 at 6 10 44 PM

This works for user selections, but not when a theme sets colors in its theme.json like this:

"core/search": {
    "color": {
        "text": "blue",
        "background": "yellow"
    }
}

In this case, the styles set by the theme will get added at the top level instead of to the button. I can fix this for the color styles by setting "__experimentalSelector": ".wp-block-search__button" in the block.json -- but this setting applies to all future block supports as well.

This isn't flexible if we want to add additional block supports that should apply their styles to the top-level Search block, rather than to just the button: for example, width or typography supports.

youknowriad commented 3 years ago

@nosolosw @aaronrobertshaw might have thoughts here.

oandregal commented 3 years ago

In https://github.com/WordPress/gutenberg/issues/28913 we discussed:

Allow selectors per property, for cases in which different properties want to target different DOM elements.

Now that we're wrapping up 5.8 work, it could be a good moment to revisit.

aaronrobertshaw commented 3 years ago

Given most block supports controls are disabled by default, their primary use at the moment would be through theme.json generated styles. That makes addressing this issue reasonably important in terms of using block supports in the wild.

I believe the proposal on the issue linked above is best demonstrated by this snippet:

    "supports": {
        "align": [
            "left",
            "center",
            "right"
        ],
        "anchor": true,
        "color": {
            "background": true,
            "__experimentalSkipSerialization": true,
            "__experimentalSelector": ".wp-social-link"
        },
        "font-family: {
            "__experimentalSelector": ".wp-social-link a"
        }
    }

Will the bulk of the work be a matter of updating the class-wp-theme-json-gutenberg.php and global-styles-provider.js uses of the experimentalSelector?

oandregal commented 3 years ago

I think that's one path we can take. Another one is to look at whether/how can we connect "elements" in the block.json, as we do in the theme.json: this other path is yet a bit fuzzy to me, but wanted to share as an alternative to foster further thoughts.

aaronrobertshaw commented 3 years ago

This issue fits into the discussion in https://github.com/WordPress/gutenberg/issues/33255 around managing styles for blocks with a wide design surface area.

A solution that allows us to apply styles to alternate rows in a table or nested nav menus would likely have this use case covered as well.

ramonjd commented 2 years ago

Also dropping image border support as a potential beneficiary for any solution we come up with: https://github.com/WordPress/gutenberg/pull/31366

The challenge for the image block is to apply border properties to the image only, and not the enveloping <figure /> block container.

The application contrasts with say, padding and margin, which we'd want to apply to the block container.

The proposal from @aaronrobertshaw above had also occurred to me as a valid path of inquiry, as it isolates the selector within a specific support. I'm not yet sufficiently knowledgable to understand the repercussions for global styles and themes.

One head-scratcher however will be how to define further granularity for other supports, e.g.,

        "spacing": {
            "padding": {
                               "__experimentalSelector": ".wp-social-link > a"
                          },
            "margin": true,
        },
aaronrobertshaw commented 2 years ago

One head-scratcher however will be how to define further granularity for other supports, e.g.,

I believe the general consensus so far is we'd be leaning more toward extending the elements API rather than expand the use of __experimentalSelector. Either way, I don't think being able to target different features, e.g. padding vs color, to different selectors will be too much of an issue.

If the elements API is opened up to allow CSS selectors in place of simple HTML elements e.g. h1, h2 etc. Each defined element/selector would encapsulate its own styles allowing greater flexibility in the theme.json styling.

An example of this flexibility could be for the image block. It could be possible to apply a border to the block's wrapper <figure> as well as a border to the <img>. Multiple padding applications become possible and so on.

I'd be interested to explore expanding the elements API in the near future once the new ToolsPanel and its surrounding work land.