-
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
Explore options to add back semantic classnames to block wrappers #38719
Comments
Another instance this happens is for link colors. <p class="has-text-color has-primary-color has-link-color">
This contains a <a href="#">link</a>
</p> A class could be applied of which color was selected. Then you could do something like: .has-primary-color.has-primary-link-color a,
.has-danger-color.has-danger-link-color a {
text-decoration: underline;
} |
Yes, this is a real issue. I've written about this in a more abstract way in issue #38694. |
The work on the Style Engine has started recently. I think it would be great to include this use case in the roadmap so we could come up with a good solution. I commented about this issue in #38167 (comment):
Do you have some ideas on how the same goal could be achieved if you were able to access the state with all applied style modifications to the block? Would it be possible to leverage WordPress hooks in any way? |
Having access styles though hooks/filters would be great, but it still does not solve the underlying problem: The loss of syntax that describe the intrinsic state of the frontend component the user wants it to have. So if having access to the styles means losing the class names, that would be a hard no from us. The practical reasons behind that are quite straightforward: You cannot target explicit styles hidden behind a selector with a random name. In a lot of larger systems you need these styles to bridge the gap between systems and to give external systems the ability to understand the state the block/component wants to be in. The most basic example of 'external systems' would be an external stylesheet. But the possibilities are limitless. From JavaScript applications that act upon having certain classes present in the DOM, towards complex DOM tree manipulation with workers in Cloudflare. To be perfectly clear here: Removing explicit classnames that describe state in favor of implicit, random classnames that describe style would effectively make any Gutenberg frontend a walled garden, which is the antithesis to openness. At least from our point of view this has to be avoided at all costs. |
I'd have to agree with that statement. Custom theme development is not jet and may not ever come to the state where we can purely rely on I can sympathize with the the issues that are trying to be addressed here. But the move away from state describing classnames would make it very very hard if not impossible to work with the generated markup. |
I had a similar issue with post-id in a page, where more as one blogroll is display and therfor the same id is used twice - which results in an validation error... Therfor I would suggest to use random-numbers in the id like this and leave the styling attributes in the class:
Important note on the randon number in the id: If the same block with the same content might be used more as one time in the same page. take care, that is getting a new number every-time its insertet in the page. |
Have CSS custom properties been considered as a solution? They could work with just regular CSS, no convoluted server rendering trickery or messy-looking unique IDs required. The defaults would appear in the global styles block, and elements with custom widths could have them inline. Example going off the conversation in #38974: .is-align-content{
max-width: var(--wp--content-width);
}
.is-align-wide {
max-width: var(--wp--wide-width);
}
.is-align-full {
max-width: var(--wp--full-width);
} <div class="wp-container wp-block-group is-align-full has-custom-layout-width" style="--wp--content-width: 50rem; --wp--wide-width: 80rem;">
<div class="wp-container wp-block-group is-align-content">
<!-- stuff -->
</div>
<div class="wp-container wp-block-group is-align-full">
<!-- stuff -->
</div>
</div> These class/variable names are just approximations since I’m not super familiar with the FSE/theme.json layout system yet. Relatedly, apologies if I’ve missed something about the architecture that makes this impractical! Fleshed this out further in: |
The classes should return, they make the most sense for custom theme developers. The button block alignment is completely useless when the 'wp_render_layout_support_flag' filter is removed. This type of update is incredibly disruptive for clients who have no technical knowledge. Their page is simply 'broken' and the developer they can email is always to blame. |
I'd love to get a sense of whether we can expect the class names to return at least till the style engine is further along in the next WordPress 6.0 release. :) |
+1 for this. The semantic class names for the block wrappers seem like a much more DRY approach and use much less code. To me, this:
seems much better than having a whole bunch of these on my pages wherever I alter a block wrapper
If I look at all the internal This is with a Theme that doesn't have a theme.json file. Whenever I save a page that was created pre5.9 it replaces the semantic classes with the newer multiple-internal-CSS-tags one. I was happy with the way things were but I can't see a way to disable all these internal CSS tags whilst retaining the semantic classes which are no longer used by 5.9+ |
I was under the impression, that the missing (removed) classes would be classified as a regression bug and therefore obviously be part of the next major release. Is that not the case? |
Having read the excellent discussion taking place here and in #38998, I'd like to jump in with a couple of thoughts.
As far as I understand it (please correct me where needed), classnames-as-API are undesirable because:
Classnames are currently an implementation detail of the wider style-processing mechanisms we are working on, meaning they aren't stable or consistent enough to work well as a public API. But theme authors are using them, and holding them to the standards of a public API (which is why new features keep falling short of these standards). This may reflect a communication problem, but it also reflects an insufficiency of the current API, because theme authors are having to reach around and find non-standard solutions to their problems. Should we obfuscate some of those generated classnames to avoid them being used in non-standard ways? As mentioned in #38998 and its accompanying blog post, there are many situations where themes may want to hook styles to a certain block state, and going down the obfuscation path will remove the possibility entirely. I believe we should avoid such brute force methods, if for no other reason than no-one stands to gain from them. It's not just theme authors that will become frustrated with not being able to implement their designs with the amount of lovingly crafted detail we have become used to in WP themes. It's also website developers building throwaway marketing campaigns, students or hackathon participants putting together quick prototypes, newbies just learning how to code. An inflexible system that's designed to be used in only one way won't serve any of those folks. We can and should educate everyone on the best way to build themes: docs and tutorials about what can be done with theme.json, and how to do it. Docs discouraging use of classnames where there's a better way to accomplish the goal. But sometimes there isn't a better way to accomplish the goal, and the best we can do in that case is provide a good safety net of consistent and meaningful classnames. |
But that is exactly what they are. By definition. That is what CSS classes have been built for and that is what their reason of existence is. For an obfuscated approach where theme.json is the only and singular source of truth, we could completely abandon css classes and just use IDs. But we already know that this approach does not scale. I am aware, that a lot of JS first developers love the obfuscated approach for its control and lockdown, but that would mean abandoning best practices defined by the last 25 years of HTML/CSS and essentially forcing a whole industry to adapt a standard workflow to a custom, untested, unscaled approach - at the scale of 43% of the web. Some would call that bold, I would use a different term.
This is the exact reason why we need well defined and dependable CSS classes, that describe the current state of a DOM element. Could not have written that better myself.
This makes an assumption of two things that are highly unlikely:
While this is true, this is not an argument for theme.json, as plugins can also influence the rendering of the styles. This is one of the core strengths and weaknesses of WordPress: A plugin can fundamentally change any aspect of the system. And until the Gutenberg team decides to abandon plugins, there is nothing that can be done about that. To quote myself from #38694:
|
Another issue with autogenerated CSS is that Wordpress and Gutenberg can no longer be used with a strict content security policy. This issue was previously raised in #9534 (comment) by @Adrian-Fischer, but CSPs are not otherwise mentioned anywhere in this repo outside of backend troubleshooting. It seems reasonable that any autogenerated CSS should be able to be removed from the page and have the target fall back to a standard set of CSS located in traditional stylesheets loaded using |
There doesn't seem to be a fix in 6.0beta. Does that mean a fix is not coming? I have a certain button style that I want to wrap differently depending on whether it is left or center aligned. There is no way for me to control that so I now have to make button-style-a, and button-style-a-left which is totally redundant and means I have to override the users choices anyway so you haven't really solved any problems with this approach. |
I used a block filter to restore the previous classes. function block_filter_buttons_add_alignment_class($block_content, $block)
{
if (empty($block["attrs"]["layout"])) {
return $block_content;
}
$classes = [];
if (!empty($block["attrs"]["layout"]["orientation"])) {
$classes[] = "is-" . $block["attrs"]["layout"]["orientation"];
}
if (!empty($block["attrs"]["layout"]["justifyContent"])) {
$classes[] = "is-content-justification-" . $block["attrs"]["layout"]["justifyContent"];
}
if (!empty($block["attrs"]["layout"]["flexWrap"]) && ($block["attrs"]["layout"]["flexWrap"] = "nowrap")) {
$classes[] = "is-nowrap";
}
if (!empty($classes)) {
$classes = implode(" ", $classes);
$search = 'class="wp-block-buttons';
$replace = 'class="wp-block-buttons ' . $classes;
$block_content = str_replace($search, $replace, $block_content);
}
return $block_content;
}
add_filter("render_block_core/buttons", "block_filter_buttons_add_alignment_class", 10, 2); |
We're also including more of these custom render functions to deal with the shifting API, but they should be unnecessary. WP has historically stood by backwards compatibility (almost to a fault), making the constant changes on point releases unnerving. |
Thank you @cbirdsong for the filtering example! With the added wp-container-x class, I just had to change the search and replace to use regular expressions.
|
There's been some roundabout discussions here that I think we need to untangle. It's obvious we need semantic classes and that premise doesn't conflict with the use of In terms of tasks, it seems we need to:
Am I missing anything? |
…utes specified. [WordPress/gutenberg#38719 In 5.9 these utility classnames were removed], which removed the ability for theme/plugin authors to assign their own custom CSS related to specific layout selections. This was mostly related to the Button block. This commit adds these classes dynamically based on attributes, rather than saving them to the serialized content. Original PR from Gutenberg repository: * [WordPress/gutenberg#41487 #41487 Add utility classnames back to blocks that have layout attributes specified] Props glendaviesnz, peterwilsoncc, andrewserong, zieladam, matveb, samikeijonen. See #56058. git-svn-id: https://develop.svn.wordpress.org/trunk@53568 602fd350-edb4-49c9-b593-d223f7449a82
…utes specified. [WordPress/gutenberg#38719 In 5.9 these utility classnames were removed], which removed the ability for theme/plugin authors to assign their own custom CSS related to specific layout selections. This was mostly related to the Button block. This commit adds these classes dynamically based on attributes, rather than saving them to the serialized content. Original PR from Gutenberg repository: * [WordPress/gutenberg#41487 #41487 Add utility classnames back to blocks that have layout attributes specified] Props glendaviesnz, peterwilsoncc, andrewserong, zieladam, matveb, samikeijonen. See #56058. Built from https://develop.svn.wordpress.org/trunk@53568 git-svn-id: http://core.svn.wordpress.org/trunk@53157 1a063a9b-81f0-0310-95a4-ce76da25c4cd
…utes specified. [WordPress/gutenberg#38719 In 5.9 these utility classnames were removed], which removed the ability for theme/plugin authors to assign their own custom CSS related to specific layout selections. This was mostly related to the Button block. This commit adds these classes dynamically based on attributes, rather than saving them to the serialized content. Original PR from Gutenberg repository: * [WordPress/gutenberg#41487 #41487 Add utility classnames back to blocks that have layout attributes specified] Props glendaviesnz, peterwilsoncc, andrewserong, zieladam, matveb, samikeijonen. Merges [53568] to the 6.0 branch. See #56058. git-svn-id: https://develop.svn.wordpress.org/branches/6.0@53569 602fd350-edb4-49c9-b593-d223f7449a82
…utes specified. [WordPress/gutenberg#38719 In 5.9 these utility classnames were removed], which removed the ability for theme/plugin authors to assign their own custom CSS related to specific layout selections. This was mostly related to the Button block. This commit adds these classes dynamically based on attributes, rather than saving them to the serialized content. Original PR from Gutenberg repository: * [WordPress/gutenberg#41487 #41487 Add utility classnames back to blocks that have layout attributes specified] Props glendaviesnz, peterwilsoncc, andrewserong, zieladam, matveb, samikeijonen. Merges [53568] to the 6.0 branch. See #56058. Built from https://develop.svn.wordpress.org/branches/6.0@53569 git-svn-id: http://core.svn.wordpress.org/branches/6.0@53158 1a063a9b-81f0-0310-95a4-ce76da25c4cd
…utes specified. [WordPress/gutenberg#38719 In 5.9 these utility classnames were removed], which removed the ability for theme/plugin authors to assign their own custom CSS related to specific layout selections. This was mostly related to the Button block. This commit adds these classes dynamically based on attributes, rather than saving them to the serialized content. Original PR from Gutenberg repository: * [WordPress/gutenberg#41487 #41487 Add utility classnames back to blocks that have layout attributes specified] Props glendaviesnz, peterwilsoncc, andrewserong, zieladam, matveb, samikeijonen. Merges [53568] to the 6.0 branch. See #56058. Built from https://develop.svn.wordpress.org/branches/6.0@53569 git-svn-id: https://core.svn.wordpress.org/branches/6.0@53158 1a063a9b-81f0-0310-95a4-ce76da25c4cd
…utes specified. [WordPress/gutenberg#38719 In 5.9 these utility classnames were removed], which removed the ability for theme/plugin authors to assign their own custom CSS related to specific layout selections. This was mostly related to the Button block. This commit adds these classes dynamically based on attributes, rather than saving them to the serialized content. Original PR from Gutenberg repository: * [WordPress/gutenberg#41487 #41487 Add utility classnames back to blocks that have layout attributes specified] Props glendaviesnz, peterwilsoncc, andrewserong, zieladam, matveb, samikeijonen. See #56058. Built from https://develop.svn.wordpress.org/trunk@53568 git-svn-id: https://core.svn.wordpress.org/trunk@53157 1a063a9b-81f0-0310-95a4-ce76da25c4cd
I know there's been general agreement that improvements are needed, but it's been 6 months since this issue was raised and, for the most part, there hasn't been a ton of improvement. Below is the CSS output from WP on a sample page of one of my test sites that simply has 11 columns blocks on it: Look at this
Just to pick a property definition at random, it defines I recognize this is all a work in process. But unfortunately, at some point, this was allowed this to reach production in its current form and now it desperately needs to be fixed. It's creating huge headaches for maintaining existing sites because of priority and specificity issues. Those of us trying to maintain sites are already scrambling during release cycles with CSS breaking changes we have to fix, and the way this CSS is applied is a force multiplier to that problem. I think it's absolutely critical that Gutenberg gets back to proper semantic class names that can be easily overridden in the theme for the 6.1 release. This just isn't a can that can get kicked down the road. Ever since 5.9, I've dreaded even minor releases because of what might break. |
There are notable improvements already merged in #40875. |
Thanks @markhowellsmead! I will definitely take a look and try them out. Will be really glad to see some progress. |
@glendaviesnz what do we have pending here? |
As far as I am aware the main pain point of Layout supports relying the random container ids was the main focus for 6.1 and this has been resolved. Post 6.1 the aim is to extend the scope of semantic class names and/or design token expressions in the style engine, and encapsulate rules into stable utility classes, as noted here. |
That's great, we should ensure this gets to be communicated properly in dev notes and theme notes. |
I think the main change was in #40875, so I'm happy to write up a short dev note for that (basically, expanding on the idea that blocks that use Layout no longer have a random container id class when they use default settings, so that the container id is only in use when the block utilises non-default settings / has unique settings set at the block level). I also have a WIP draft PR (#42619) to start documenting how the Layout support works (and the classnames it outputs). I've held off on pushing forward that PR during this period just before the feature freeze since things are still a little in flux, but plan to dust it off once we know exactly what's made it into the 6.1 Beta. |
…utes specified. [WordPress/gutenberg#38719 In 5.9 these utility classnames were removed], which removed the ability for theme/plugin authors to assign their own custom CSS related to specific layout selections. This was mostly related to the Button block. This commit adds these classes dynamically based on attributes, rather than saving them to the serialized content. Original PR from Gutenberg repository: * [WordPress/gutenberg#41487 #41487 Add utility classnames back to blocks that have layout attributes specified] Props glendaviesnz, peterwilsoncc, andrewserong, zieladam, matveb, samikeijonen. Merges [53568] to the 6.0 branch. See #56058. Built from https://develop.svn.wordpress.org/branches/6.0@53569
…utes specified. [WordPress/gutenberg#38719 In 5.9 these utility classnames were removed], which removed the ability for theme/plugin authors to assign their own custom CSS related to specific layout selections. This was mostly related to the Button block. This commit adds these classes dynamically based on attributes, rather than saving them to the serialized content. Original PR from Gutenberg repository: * [WordPress/gutenberg#41487 #41487 Add utility classnames back to blocks that have layout attributes specified] Props glendaviesnz, peterwilsoncc, andrewserong, zieladam, matveb, samikeijonen. See #56058. Built from https://develop.svn.wordpress.org/trunk@53568
Since this comment was written things have improved, but there are still some very strange choices with the way CSS is being structured and deployed here. For instance: .wp-block-columns.wp-container-3,.wp-block-columns.wp-container-6,.wp-block-columns.wp-container-9,.wp-block-columns.wp-container-12,.wp-block-columns.wp-container-15,.wp-block-columns.wp-container-18,.wp-block-group.wp-container-25,.wp-block-group.wp-container-26,.wp-block-group.wp-container-27,.wp-block-group.wp-container-28,.wp-block-group.wp-container-29,.wp-block-group.wp-container-30,.wp-block-columns.wp-container-40,.wp-block-columns.wp-container-43,.wp-block-columns.wp-container-46,.wp-block-columns.wp-container-49,.wp-block-columns.wp-container-52,.wp-block-columns.wp-container-55,.wp-block-group.wp-container-62,.wp-block-group.wp-container-63,.wp-block-group.wp-container-64,.wp-block-group.wp-container-65,.wp-block-group.wp-container-66,.wp-block-group.wp-container-67 {
flex-wrap: nowrap;
} These blocks already have an .is-nowrap {
flex-wrap: nowrap;
} The stack variation of the group block has the same issue. What currently is generated: .wp-block-group.wp-container-31,.wp-block-group.wp-container-32,.wp-block-group.wp-container-33,.wp-block-group.wp-container-34,.wp-block-group.wp-container-35,.wp-block-group.wp-container-36,.wp-block-group.wp-container-68,.wp-block-group.wp-container-69,.wp-block-group.wp-container-70,.wp-block-group.wp-container-71,.wp-block-group.wp-container-72,.wp-block-group.wp-container-73 {
flex-direction: column;
align-items: flex-start;
} Again, the .is-layout-flex.is-vertical {
flex-direction: column;
align-items: flex-start;
} Also, to keep this from being entirely negative – the ability to use |
…utes specified. [WordPress/gutenberg#38719 In 5.9 these utility classnames were removed], which removed the ability for theme/plugin authors to assign their own custom CSS related to specific layout selections. This was mostly related to the Button block. This commit adds these classes dynamically based on attributes, rather than saving them to the serialized content. Original PR from Gutenberg repository: * [WordPress/gutenberg#41487 #41487 Add utility classnames back to blocks that have layout attributes specified] Props glendaviesnz, peterwilsoncc, andrewserong, zieladam, matveb, samikeijonen. Merges [53568] to the 6.0 branch. See #56058. Built from https://develop.svn.wordpress.org/branches/6.0@53569 git-svn-id: http://core.svn.wordpress.org/branches/6.0@53158 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Hi, I want to add an issue: Since wordpress 6.2 the default output for
But why change the default align-items to center? This destroys many layouts. Possible solution: |
Thanks for the feedback @mehne. The
In WordPress 6.2, vertical alignments are allowed in both horizontal and vertical flex orientations. So, as of #47134, you should be able to adjust the If there's anything not covered there, feel free top open a separate issue, though! |
Thanks for your answer @andrewserong. |
Description
As noted here, and here the move to random class names for applying layout styling in the likes of the Buttons block has removed the ability of themes/plugins to easily target elements based on layout.
For instance, in WP 5.8 a button block that was centrer aligned would have a class assigned to indicate this:
but in 5.9, a button block that is center aligned just has a random classname assigned to apply these styles:
Ideally this should be done in a way that does not involve serialising these classnames in the saved block content, so the Style engine seems like the best place to explore adding these back as this can enable it to be done at runtime from the current block semantics in both the editor and frontend.
Additional discussion has taken place here and here, in relation to the value of semantic classnames to allow themes to override styles.
This needs to be balanced out with a desire to not expose too many classnames that may not be intended as a permanent API, but which theme authors may assume they can depend on.
The text was updated successfully, but these errors were encountered: