WordPress / gutenberg

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

Attach css and js to patterns #61881

Open Lovor01 opened 5 months ago

Lovor01 commented 5 months ago

Problem

In the early days of Gutenberg, I used to build block for everything to create pages. That was such, because I needed that user can insert complex unit as a whole. Nowadays, it is much faster working with patterns, creating a group of elements and creating pattern out of that. However, there is still problem with optimising css/js if those patterns require special css or js and most of them do. I can either enqueue all needed css/js on every post/page or eventually guess on which pages user will need those patterns and enqueue css/js only there. It would be much more useful that system remembers a pattern being used on a page and enqueues given css/js only there where pattern is used, much like with blocks.

Solution

Developing a system which would somehow store occurence of pattern on post/page, either as another comment in content (similar to block) or post metadata. Also, enhancing pattern definition so css/js could be attached to it. This part would be very easy, since pattern has a unique slug, css and js could be enqueued with dedicated functions receiving css/js url and pattern slug. e.g.

register_pattern_script('url', 'pattern_slug');
register_pattern_style('url', 'pattern_slug');
eirichmond commented 2 months ago

I'm on board with this, but I’m concerned there might be a technical issue in managing the logic. Technically, patterns can be saved to and removed from the database. The first challenge would be how to reliably identify a pattern using a slug. This might not be a significant issue since the pattern is saved with the slug as the 'post_name.' However, if the slug were ever changed, the logic connecting the pattern to the enqueued script or style could break. The same risk applies if the pattern were removed from the database, potentially leaving redundant logic in plugins or themes. This might not be a problem with pattern files but could certainly become an issue with database-saved patterns.

Lovor01 commented 2 months ago

I'm on board with this, but I’m concerned there might be a technical issue in managing the logic. Technically, patterns can be saved to and removed from the database. The first challenge would be how to reliably identify a pattern using a slug. This might not be a significant issue since the pattern is saved with the slug as the 'post_name.' However, if the slug were ever changed, the logic connecting the pattern to the enqueued script or style could break. The same risk applies if the pattern were removed from the database, potentially leaving redundant logic in plugins or themes. This might not be a problem with pattern files but could certainly become an issue with database-saved patterns.

For patterns saved in database, a copy of css/js could be saved to database as well, either as post meta or in separate table, or alternatively together with pattern. Having this in database would solve the problem of orphaned files, as this would be removed together with pattern when user chooses to delete pattern.

gziolo commented 2 months ago

@fabiankaegy proposed:

It made me think there might be some overlap between Section Styling and the need for custom CSS for Patterns. I'm not familiar enough with the work championed by @aaronrobertshaw, but it would be great to have a coherent vision of the best approach for adding additional design tweaks to existing patterns.

Regarding the need for JavaScript, could you expand what type of functionality would you like to add to patterns on the frontend? That's the area where Interactivity API should eventually become the solution, so maybe we need some way to automatically enqueue scripts based on the directives included in the HTML markup.

aaronrobertshaw commented 2 months ago

Thanks for the ping, and for writing up this @Lovor01 πŸ‘

Styling patterns might be an easier first step than augmenting them with custom JS.

It made me think there might be some overlap between Section Styling and the need for custom CSS for Patterns.

The styling of patterns using the "Section Styles" feature (aka enhanced block style variations) is on the radar and might already be employed by some themes.

I believe the approach taken to date is to define a block style variation for a container block. Then use that container block as the root for the pattern with the block style variation applied.

The CSS for the block style variation is only generated and added to the page when a block with the variation applied is present.

it would be great to have a coherent vision of the best approach for adding additional design tweaks to existing patterns

@richtabor might be best positioned to share a vision around this aspect.

That's the area where Interactivity API should eventually become the solution.

I had the same initial thoughts.

So hopefully in the not too distant future this will all come together with section styles and the interactivity API both augmenting patterns in a way that satisfies the needs expressed in this issue.

Lovor01 commented 2 months ago

@gziolo : I'll give you an example, I didn't use Interactivity API yet, it is a recent feature - but given the description it may cover this use case, I am not sure. For example, I needed JS attached to pattern where pattern is comprised of video and three buttons below, all in a group block. The three buttons serve to rewind video on specific points, and therefore I needed JavaScript for that. User wanted to insert this pattern on several pages and it wouldn't work if javascript is not enqueued on the page where pattern is inserted.

Lovor01 commented 2 months ago

Thanks for the ping, and for writing up this @Lovor01 πŸ‘

You are wellcome!

I believe the approach taken to date is to define a block style variation for a container block. Then use that container block as the root for the pattern with the block style variation applied.

The CSS for the block style variation is only generated and added to the page when a block with the variation applied is present.

it would be great to have a coherent vision of the best approach for adding additional design tweaks to existing patterns

It still seems to me this is somewhat clumsy solution - I heard several complaints about patterns not being nearly useful as they could since they do not pack with css to style them in certain way. I believe creating pattern as a container which can have content and optionally styling and javascript would significantly modularize that approach and making patterns more useful. Additionally, themes would be allowed to override pattern styling, so they can style colors, fonts, borders etc. to fit overall look of the theme. But what theme would probably not style for the pattern is layout of the pattern (e.g. special flexbox or grid styles, which possibly could not be achieved with built-in block editor features), transparency of some elements, filters, positioning, transformations and many more, since block editor supports only subset of possible css styling

Further, Sections styles do not pack css together with pattern, so you have to have variation registered in code - it is not easy to share such pattern.

aaronrobertshaw commented 2 months ago

Appreciate the continued feedback @Lovor01 πŸ‘

As more discussion takes place, things can definitely evolve on this front. I don't think anything is set in stone at this point.

It still seems to me this is somewhat clumsy solution

There's a little more to this approach that should be considered. By defining a block style variation that is somewhat generic in name, e.g. is-style-section-1, it opens up lots of portability for the pattern and makes it capable of adapting better across themes. If a theme defines a variation of the same name, it will pick up the appropriate styles, immediately appearing as though it belongs in the theme. This is amplified further when different theme style variations then redefine the block style variation.

In my opinion, bundling one set of opinionated CSS within a pattern greatly reduces its potential applications and flexibility. JS on the other hand I can understand being more 1:1 with a pattern and the interactivity API should serve that need well.

But what theme would probably not style for the pattern is layout of the pattern (e.g. special flexbox or grid styles, which possibly could not be achieved with built-in block editor features)

I believe these layouts are achievable using the layout block supports already available. The best place to explore these is probably the controls on the Group block first, see the Row, Stack, and Grid block variations. If there are specific style values not supported in the UI yet, the custom CSS field within theme.json and Global Styles allows for those to be set as well.

transparency of some elements, filters, positioning, transformations and many more, since block editor supports only subset of possible css styling

As noted above, these can be covered by the Custom CSS feature of Global Styles or the css property in theme.json.

Further, Sections styles do not pack css together with pattern, so you have to have variation registered in code - it is not easy to share such pattern.

This is a good point. It could be debated though whether patterns in general should require such opinionated styling.

There has been some work done to allow Theme.json settings to be defined within block markup but so far this doesn't extend to embedding style variations values. The difficulty here is likely down to those styles blocking the expected ability for the theme and site receiving the pattern to override them effectively. Perhaps some form of opt-in capability to receive such styles would be beneficial but it needs further thought and exploration.

I hope that helps some 🀞

Lovor01 commented 2 months ago

There's a little more to this approach that should be considered. By defining a block style variation that is somewhat generic in name, e.g. is-style-section-1, it opens up lots of portability for the pattern and makes it capable of adapting better across themes. If a theme defines a variation of the same name, it will pick up the appropriate styles, immediately appearing as though it belongs in the theme. This is amplified further when different theme style variations then redefine the block style variation.

Isn't that a problem - naming should be unique to whole wordpress.org, is-style-section-1 could refer to many patterns? And at the same time such generic name does not convey and useful info about the pattern?

In my opinion, bundling one set of opinionated CSS within a pattern greatly reduces its potential applications and flexibility. JS on the other hand I can understand being more 1:1 with a pattern and the interactivity API should serve that need well.

As I wrote earlier, theme should be able to override pattern embedded css. There are many css styles which could be necessary for pattern to display correctly. These include image positioning and other related properties, special css grid properties which are not available in editor, animations, etc... Theme can't know specifics of some pattern and that should be left to css embedded in pattern. Theme should be able to override all of these properties, but theme would be most concerned with colors, font styles, margins and paddings and similar.

Lovor01 commented 2 months ago

What I meant is that many css properties are lacking in the block editor and it may not be feasible to add them all as GUI options, but they might be needed for some patterns (it was so in my case) - so why don't let pattern creators share that embedded css together with pattern, so pattern displays correctly without additional interventions?

aaronrobertshaw commented 2 months ago

Thanks for the continued feedback @Lovor01 πŸ‘

Isn't that a problem - naming should be unique to whole wordpress.org

The primary use case for the generic block style variation names/classes e.g. is-style-section-1, is that patterns in public directories can avoid opinionated styling and simply apply a common (perhaps in future standard) block style variation class. Then if a theme supports that block style variation, it can define the appropriate styling so such a pattern matches the overall look and feel. If a theme doesn't define styles for the variation, the pattern appears generic and unstyled.

If patterns are being defined within a specific theme and styled via variations, there's no restriction on what the naming could be.

And at the same time such generic name does not convey and useful info about the pattern?

Block style variations can define both a slug, used for the CSS class name, and a label which can convey meaning to the user about the variation. I'm not sure block style variations should be responsible for communicating information about a pattern itself though.

There are many css styles which could be necessary for pattern to display correctly.

Most blocks already have a style object within the block attributes. One option might be a block support that will generate CSS styles from that style object's custom CSS property. I'm not 100% up to speed on the current theme.json/global styles custom CSS features, so it could be possible this option isn't that far off being achievable.

What I meant is that many css properties are lacking in the block editor and it may not be feasible to add them all as GUI options

This is where the custom CSS property for block types or block style variations within Global Styles can help.

Lovor01 commented 2 months ago

Hey, thanks for taking time to answer @aaronrobertshaw !

I'm not sure block style variations should be responsible for communicating information about a pattern itself though.

That's my mistake, the class name should not communicate information about pattern, but about style variation.

I see the point in making style generic so I can agree to that.

On the other hand, I would return to the point of this issue, attaching css and js to pattern. Perhaps Gutenberg authors would like to avoid that in order to not make patterns too opinionated. Yet, in my work I find constant need for specifically styled patterns which are unique to some page or unique to the site. This means that I have to put a lot of custom css in theme.json, or in the site editor styling text area and this css is not easy to handle. It is not well readable, does not have linting nor other editor features like suggestions.

My proposal remains to allow attaching css and js as files in theme or plugins and that these files can be distributed together with pattern (either as zipped file consisting of more files or embedded inside pattern definition and hence single file). This css should be written in such way that theme can still style colors, fonts, etc. inside pattern if desired.

aaronrobertshaw commented 2 months ago

Yet, in my work I find constant need for specifically styled patterns which are unique to some page or unique to the site.

This is definitely a valid use case. No arguments here.

This means that I have to put a lot of custom css in theme.json, or in the site editor styling text area and this css is not easy to handle

Future iterations of the section styling feature might also allow for a combination of the traditional and theme.json approaches to defining block style variations. This may help reduce a little friction while still allowing Global Styles supported styles to be configurable by end users.