-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Block style variations now use hashed classnames, specificity issues #64856
Comments
@chrisandrew-dev Thanks for reaching out. The hashed classnames are now used to support some of the newer advanced uses of block style variations that have theme.json declarations. They can support inner element and block type styles (e.g. headings/paragraphs/buttons within a group could be styled by a group block style variation). You can also have some pretty complicated nesting situations with those styles where the right style needs to take precedence, for example:
While I didn't work on the feature directly, my understanding is that load order and specificity wouldn't be able to solve this issue alone, so separate classnames are generated. @aaronrobertshaw could add some more detail, though I gathered a lot of this from a similar discussion in slack (https://wordpress.slack.com/archives/C02QB2JS7/p1720158357236439) that Aaron and I were involved in. The other point you mention about the load order/specificity of the previous block styles, that does seem like an unfortunate consequence of the specificity changes - it was important that those styles don't override the new block style variation selectors, and we also want to keep specificity low, but that means it creates more issues like this. There's a similar discussion in #64225. There's also an issue now that style variations can be edited in the global styles UI, the older static css implementation can become out of sync with the look of the block style variation, so that needs some thought. Maybe the older block variation styles should only be loaded when there's no theme.json declaration, and then load order adjusted if needed. Or perhaps it's better to generate selectors like |
Hmm, but at what cost and to whose benefit? Whether or not output by a block instance, applying consistent base styles to common HTML elements (headings, paragraphs, lists buttons, links...) shouldn't be road-blocked by experimental or niche features, in my view.
Since
"is-style-outline" is still present in the generated markup but has no affect per the above. Duplicate rulesets appear to be injected into the head for every instance of a given style variation on a page, anyway (there are two "outline" button variants on this page):
|
Thanks for taking the time to write up the detailed issue @chrisandrew-dev and the ping @talldan 👍
This is correct. As Dan notes this was required to support nested applications of block style variations.
The situation is a little more complex than described here. Which makes this statement perhaps a little incomplete or inaccurate. For backwards compatibility with classic themes, the default block style variation styles had to be kept in the block library stylesheet for the Button block. This is because classic themes wouldn't get any default variation styles from the core theme.json. As styles should be loaded in the following order and at the same specificity (
it leads to what you are suggesting that default button element and block type styles are overriding the variation's defaults. You are correct, the theme.json element and block type styles override the block style variation defaults in the block library stylesheet that supports classic themes. The missing piece though is that those default variation styles were also added to the core theme.json file as a block style variation definition. The result is the defaults added to the core theme.json are loaded last as per the list above. Restoring them such that the variation defaults aren't actually overridden by default block styles. In short, there are two defaults, one required by classic themes in the block library stylesheet, and a second in the core theme.json for block themes. I'm not arguing this is an ideal scenario but it was the only functional option for WP 6.6.
I might not be understanding this challenge fully. What is leading to the choice to use block style variations to style non-block elements?
This should be the case currently. There is the unfortunate situation with the default button outline styles also needing to be in the core theme.json file to ensure this. It adds confusion but was unavoidable to maintain backwards compatibility for classic themes.
I'm not sure what this would look like. Do you have something more concrete in mind that would also satisfy the need for nested block style variations?
@talldan's explanation here is spot on.
It appears to me there is confusion around which styles are being overridden. The default variation styles in the block library are expected to be overridden, both by theme.json element and block type styles as well as the default block style variation styles in core theme.json.
Only block style variations that have been registered in the Block Styles registry and have an entry in theme.json are present for further customization via Global Styles. Traditional block styles that enqueue a CSS stylesheet or inline styles aren't editable in Global Styles. A theme author needs to chose one approach or the other i.e. traditional or global styles.
I might just be having a bad day but I'm not following this suggestion either.
Can you expand on how block style variation styles are blocking the application of element styles?
The
This is both for backwards compatibility and used by block supports to detect when a variation has been applied to generate the instance specific classname and styles.
It is correct that each instance of a block style variation adds its own style. This is done to solve the nested use case discussed. At this stage, the Button block's variation is treated the same as any other block style variation. It could be possible to have a list of blocks that do not support nested variations and alter the generation of styles. Apologies for the wall of text, I hope it helped clarify a few things though! 🤞 FYI, I'll be away for around a week and a half, so unfortunately I won't be able to continue participating in this discussion until early-mid September. |
@aaronrobertshaw & @ talldan Thanks for the clear, detailed and timely responses - really helpful.
Aha, now it makes sense why this is happening.
In the case of buttons, it's to ensure all buttons are styled consistent with our design, and so rulesets applied to one button apply to another (of the same style variation), regardless of whether the button is an instance of a button block or static markup added to a header, footer, form or other PHP template part.
We've been incrementally adopting new features into our new and existing client sites for some time. This appears to suggest there's no clear migration path from classic themes to block themes..?
I'm not familiar enough with the issue your team was trying to solve to suggest an alternative. At a fundamental level, and given two identical HTML elements, I'd expect the element with the additional "is-outline-style" class to have the class rulesets applied.
This is perhaps the most poignant point in the context of developing enhancements to existing projects, or expediting development using our in-house boilerplates.
A PHP project embracing select block theme features can no longer leverage variation classnames to style block and non-block elements (buttons, in this example) consistently, and in one place.
I might have missed something critical but from what I can tell, the duplicate rulesets are identical. There is no unique style property in the examples shown and the entire ruleset is redeclared for each button rather than being scoped to "is-style-outline". I can see this becoming very bloated as I build out the page.
It certainly helped improve my understanding of the changes, thank you. I hope the points raised stimulate further discussion and that hybrid theme developers and agencies like our own have a clear migration path, moving forward. Enjoy your break! |
Thanks for taking the time to provide the continued feedback and clarifications 👍
The issue for classic themes was that they still needed the default styles to belong somewhere when they don't have a theme.json file. I don't think the presence of these styles here prevents any migration of the theme into a block theme.
If you register a block style using the traditional approach of enqueuing a stylesheet, that stylesheet would target the simpler To me, the problem described with applying block styles to static elements is down to trying to repurpose a feature intended to work with blocks only. We might need to see how common a use case this is before the feature could be extended to support it.
As eluded to above, if a block style variation is registered along with a stylesheet, the block style variation class will be applied to the block as before. The styles in the block style's stylesheet can target that directly. That class can be applied to static elements if desired and therefore styled as expected. This issue now looks like it can be isolated somewhat to the button block only as it had a core block style registered and was then also configurable via Global Styles. One possible workaround, although I'm not sure how palatable it would be, could be to deregister the core Button outline block style, then register a new custom block style using the traditional approach. This wouldn't be configurable via Global Styles and would then use the simple non-unique classname allowing you to use it for your use case.
Maybe not missed exactly but discarded perhaps? The need is to support nested applications of block style variations as outlined in this comment. Take the following quick example, there's a section (Group) with a variation applied, within that there's a pricing table (Group/Row block) with a different variation applied, and finally in each column there's more content including another group with the section's variation applied. In this case if the group block style variation applied to the pricing table was defined after the section's and the variations only used the non-unique class
This was a known issue but perhaps its severity was underestimated as it was not expected that block style variations were being used as per your use case. This is why I suggested it could be possible in a future iteration of the feature to have certain block types that wouldn't support nesting variations and therefore wouldn't need the application of variations styles per instance. The button block would be the obvious candidate for this.
🙇 Thanks. |
Description:
Recently, WordPress appears to have changed how block style variations are applied, requiring a hashed classname for styles to be correctly applied. For example, the "outline" button variation now requires a classname in the format
is-style-outline--{hash}
, whereas previously,is-style-outline
was sufficient.This change has introduced a few issues:
:root :where(.wp-element-button, .wp-block-button__link)
overrides:root :where(.wp-block-button.is-style-outline>.wp-block-button__link:not(.has-background))
.theme.json
(also heavily encouraged in the developer docs). Additionally,:hover
,:focus
, etc. styles defined intheme.json
(styles.elements.button[":hover"], .etc) aren't applied to the "outline" button variation, for example.Expected Behavior:
Additional Context: The previous implementation where "is-style-outline" was sufficient allowed for more straightforward styling across various button / link elements, including those outside the block editor.
Suggested Solution: Consider adjusting the order of style declarations or revising the specificity rules to ensure that variation styles override default styles, without relying on individually hashed elements and duplicate rulesets applied in the document head. Additionally, providing a way to opt-out of hashed classnames for consistent styling across different parts of the site would be beneficial (why are they necessary?).
Step-by-step reproduction instructions
Screenshots, screen recording, code snippet
Edit: Removed because LICEcap only recorded mouse cursor.
Environment info
Please confirm that you have searched existing issues in the repo.
Please confirm that you have tested with all plugins deactivated except Gutenberg.
The text was updated successfully, but these errors were encountered: