Improving our saving/rendering of block styles #37495
Replies: 9 comments 11 replies
-
Thanks for raising this @youknowriad, it's a very welcome discussion!
I love the idea of a dedicated "styles engine" / API that can centrally consolidate and manage the different approaches each of the block supports currently use to implement their rendering. However it gets implemented, it'd also be great to include in scope accessing the generated styles via the REST API (to resolve issues like in #35376). Ideally the rendered markup can be easily matched / paired to the generated styles. A couple of other parts that would be good to deal with in the implementation: at the moment, block supports that generate a For a consumer of the generated markup (either the front end of the site, or a block preview of a post within the editor as in #35376) it'd be great to be able to either fetch the relevant styles generated for that post, or to be able to reconstruct them based on the rendered markup, without requiring access to the raw block comments stored in
I really like this idea. Dealing with deprecations surrounding styling changes is a big pain point, and it'd be great to skip it if we can. A couple of points in favour of leaning toward server-rendering block supports styles:
|
Beta Was this translation helpful? Give feedback.
-
It's great to see us moving to address these concerns, thanks for starting the discussion @youknowriad! Put me down as another +1 for a dedicated styles engine. In addition to what has already been raised. I'd like to see it be able to offer more flexibility to where within a block the styles are applied. At the moment, we allow skipping serialization of block support styles on individual blocks. This generally creates problems with theme.json or Global Styles due in part to a limited Elements API. An example of this issue is adding border support to the Image block or the application of block support styles to the Search block.
This would also be a great addition to whatever solution is implemented.
Deprecations have been a concern for a while as the block supports evolved. It has also lead to increased code to handle backwards compatibility e.g. moving from unitless numeric values to strings containing units for border radius. A change in approach here might also offer the opportunity to make some code more concise and easier to reason about.
I like the idea of being able to auto-upgrade all blocks if possible.
This sounds like a big win to me! Robust but still with the flexibility for us to iterate on it. |
Beta Was this translation helpful? Give feedback.
-
Thanks for writing up this issue. More broadly, having a consistent/single, dedicated API to manage styles would be terrific also from a contributor viewpoint. A case in point: I've been researching into (potentially) adding block support for writing-mode (PR), and have spent some time pondering the question: "Where am I going to put the CSS?" There are several approaches to follow. At first my mind turned to block container inline styles, such as we use for padding, margin and many other supports. No, I might need up to five CSS definitions. There's also printing out block-specific CSS in a styles tag. Duotone does it this way. Similarly, so does Layout. This would theoretically work, but it would add yet another bunch of rendering code for a bespoke feature. I haven't yet looked closely at the Elements styles. With a "styles engine" I'm imagining being able to register styles and styles metadata in a central hub. The engine would render my posts' consolidated styles to the editor and frontend in the background. I wouldn't have to concern myself with the rendering engine at all, only my block's styles, saving a bunch of time I would have otherwise spent on worrying about implementation details. |
Beta Was this translation helpful? Give feedback.
-
I've added a tracking issue to consolidate many of the ideas from this discussion (and to track our work of course). Feel free to add / edit the to-do list items as needed! |
Beta Was this translation helpful? Give feedback.
-
Adding a quick note for a tie-in to broader block validation issues. A more robust block-loading process with a stronger "parser" (quotes because it's not parsing text but rather the block attributes and inner blocks that a block is transforming to input) should open up new opportunities to handle this more gracefully. Your recent changes in #37942 made me think of this, even though that's a slightly different topic. I'll be writing up some issues soon on validation and I'll try to link back here. |
Beta Was this translation helpful? Give feedback.
-
Starting a project over at https://github.com/orgs/WordPress/projects/19/views/1. We'll be putting meat on the bones and adding issues as we progress. |
Beta Was this translation helpful? Give feedback.
-
Do you also plan to optimize the CSS based on the contents of the CSS class declaration? In the example below, we generate a single class for a preset, but if the color value is user-defined, it is being set inside of the Screen.Recording.2022-01-27.at.14.00.33.movWe could solve this by hashing the contents of the css declaration similar to how many CSS-in-JS frameworks do it. Goober is one (and probably the simplest) example: https://github.com/cristianbote/goober/blob/master/src/core/hash.js#L39-L41 |
Beta Was this translation helpful? Give feedback.
-
EDIT: This was meant as a reply, not a top-level comment. Sorry for the confusion!
Upon taking a second look I think you wouldn't even need to hash anything. I think we could have a simple in-memory "cache" (a regular JS object would do) and compare strings:
here (once you stringify), the
What do you mean by "customizations per block"? I understand your point - premature optimization, etc. 🙂 I'm not sure if this is what you meant but this optimization would make sense only if the engine were to process the styles globally and not per block. If the CSS rules are generated per block then this optimization might not help very much because we you will still end up with duplication. Using a similar example as before, a duplicate CSS rule would be generated for both
|
Beta Was this translation helpful? Give feedback.
-
Hey @youknowriad what do you mean by this? I'm having trouble understanding. Could you illustrate with an example? 😀 |
Beta Was this translation helpful? Give feedback.
-
Over time, we build an impressive list of block supports to customize the look of different styles: borders, colors, background, spacing, layout, duotone, typography... but these things have been implemented organically adding one by one and solving potential complexities as we face them. The result is that we have different approaches depending on the styles we're changing and their values:
Inconstency1
Inconsistency2
About the save mechanism (inconsistency 1)
Can we solve this by introducing a "styles engine" that has two implementations: one on the server, one on the client. The client implementation is opt-in (used in the editor and also can be used by third-party block editors to render their blocks as needed), the server implementation is preferred for the frontend in WordPress.
About the attribute saved value (inconsistency 2)
Can we solve this by replicating the "style" attribute format used in global styles entirely in blocks (getting rid of the preset values and using the preset format we use in global styles)?
On deprecation and validation
The downside of both the proposed changes above is that it creates a lot of deprecations for all core blocks basically. We discussed in the past whether "style" and "classnames" markup changes should actually be considered invalid content in the past, so potentially we could start by implementing this: Consider style or classnames differences in the saved markup as valid diff (ignore them)
On the block supports
The changes above will impact third-party blocks as well, how to solve the backward compatibility here:
On the advantages of the new approach
The style engine will be something that we can change over time without deprecations and without breaking changes. For instance we could evolve to introduce fluid typography automatically.
cc @WordPress/gutenberg-core @andrewserong @aaronrobertshaw
Beta Was this translation helpful? Give feedback.
All reactions