Global Styles: recap & next steps #22296
Labels
[Feature] Themes
Questions or issues with incorporating or styling blocks in a theme.
Global Styles
Anything related to the broader Global Styles efforts, including Styles Engine and theme.json
I was looking at how to make progress for the Block Style System and unblock the managed CSS PR. I've noticed that we've been having some scattered convos in issues/PR so it's been difficult to follow, so I thought it'd be a good idea to recap and focus on the next steps.
I'd like the next step for Global Styles to be: how do we allow themes to style the same things a user can at the block level?
Background
The block style system needs to define how the style units work together, accounting for local & global styles. At the scale of the WordPress ecosystem, themeability comes with a lot of complexity, unnecessary CSS loaded in the page, and specificity wars due to the competing needs of core and 3rd party components (themes, blocks, plugins).
One of the key issues is that we lack semantic mechanisms to style blocks in the many contexts they can be used. For example, a paragraph can be a top-level element in a document, but also be present within a column or group block in a sidebar --- it may need different styles for each context.
Take this simple piece of HTML (an actual pattern registered by core) as an example:
It's made of the columns block and some paragraphs, something along these lines (source code):
Depending on context, each paragraph has a different meaning. Design-wise, it can be divided into sections containing three semantic elements: number, title, description. Each piece maps to an HTML
<p>
element with a different color and font size, which can be considered the style hooks of the block.Style Hooks for Blocks
How do we make a pattern like the above themeable?
In the first iteration, we tried declaring CSS variables per block to expose its "style hooks" (see). We'd have
--paragraph-color
,--paragraph-font-size
, and so on. This had great power (allow you to target individual pieces), but it was also too specific: if you account for 3rd party blocks, the explosion of variables makes this unwieldy for themes to keep up with. It is also fragile for nested content: do we use specific variables for paragraphs within patterns such as--pattern-numbered-features-title-color
,--pattern-numbered-features-description-color
? If so, we run into situations where the user can't modify the structure of a pattern, otherwise they'll lose the styles.The second iteration was about only using general CSS variables such as
--color-primary
,--color-secondary
(see) and map them to blocks. This was too opinionated and themes needed the ability to change those mappings. It didn't solve nested content on its own either.We had a brief experiment to use CSS variables at the block level, that we reverted back due to cascading issues and to make sure other pieces were ready when this landed: introducing variables into blocks needs themes to adapt so we need to be mindful about how/if/when we do it.
After these iterations, it looks like the core problem we need to solve isn't really about using CSS variables to mark "style hooks", but about how do we target the style hooks of a block depending on its context? How do we add that semantic layer without breaking backward-compatibility? Currently, the way themes deal with this is by using CSS selectors. What if we could make selectors work well at the scale of WordPress?
Managed CSS
The idea is that, instead of having to write CSS that overrides existing CSS by adding specificity, components of the system declare their design choices as per the existing style hooks for blocks. Gutenberg takes those styles and merges them into a single stylesheet.
Let's go back to the example pattern above. The output CSS that we need to style the pattern could be something like this:
The styles within each style rule should be the result of taking into account blocks & theme choices.
The managed CSS PR proposes that components use a pre-defined format to declare their preferences. Themes, for example, would use a
theme.json
file such as:Core would come with a similar file where styles for core blocks & patterns are declared, and 3rd party blocks would do the same.
Benefits
"Managed CSS" means that theme authors focus on what they do best: provide design direction. It abstracts away some of the peculiarities of how WordPress works and the inner implementation of blocks, and adds a semantic layer to design.
Because CSS is managed, Gutenberg can adapt it for different contexts (editor, front), and reduce the specificity wars. It also means less CSS will be shipped. If block markup changes but the style hooks remain the same, theme authors won't need to do anything: it's the block responsibility to maintain the mapping between style hooks and the specific implementation.
Note that this approach is agnostic about the styles used within each style rule: it doesn't require blocks come with any CSS Custom Properties, although we can use them when it makes sense.
Tasks
So, what do we need to do so a theme can use a
theme.json
file as described above to style the same things a user can at the block level?theme.json
. This needs to account for editor styles wrapper in the editors to avoid style leaks, etc. Look into whether we can expose this as an external stylesheet instead of an embedded stylesheet.The text was updated successfully, but these errors were encountered: