Custom CSS: Allow defining custom selector for this global styles feature#75799
Custom CSS: Allow defining custom selector for this global styles feature#75799aaronrobertshaw merged 5 commits intotrunkfrom
Conversation
1037d3f to
70d8fac
Compare
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Size Change: +144 B (0%) Total Size: 6.84 MB
ℹ️ View Unchanged
|
ramonjd
left a comment
There was a problem hiding this comment.
I tested this branch solo and with #75786 applied.
When a block type defines a css feature selector in its block.json selectors config, the Global Styles custom CSS output should honor that selector instead of always using the block's root selector
The change to declare a css-specific selector makes sense to me. 👍🏻
t-hamano
left a comment
There was a problem hiding this comment.
Thanks for the PR!
The changes seem good, but I have three suggestions:
- Let's update the block.json schema.
- Regarding the selector key, what do you think about using
customCSSinstead ofcss? - I think this PR is both an enhancement that introduces new selector keys and a bug fix. What do you think about backporting this PR and #75786 to WP 7.0?
|
Appreciate the thorough review and thoughts @t-hamano 👍 For the selector key, I think
It would have been nice if the Custom CSS feature kept consistent keys between the block supports and theme.json but this doesn't appear to have been the case. Additionally, as the block nodes from the theme json class are exposed by a filter the Regarding backporting, I'd consider this more a bug fix. The selectors API was designed to let block authors control which selector is used for each feature's styles. Custom CSS not honoring that is an oversight that goes against a block author's reasonable expectations. It's not introducing new functionality so much as making existing functionality work as intended. That said, I don't think this is very high priority so while I'd support backporting both to WP 7.0 if it was really desired, it might not be worth the hassle.
I've updated both the block.json schema and the Selectors API docs |
When generating custom CSS rules for a block type via Global Styles, use the block's css feature selector from the selectors config if defined, falling back to the root selector. Also skip the css selector in get_feature_declarations_for_node to prevent it being consumed as a regular style feature.
Update generateGlobalStyles to check featureSelectors.css before falling back to the root selector when processing block custom CSS. Adds tests for both the feature selector and root fallback cases.
c1906f4 to
cddc430
Compare
t-hamano
left a comment
There was a problem hiding this comment.
@aaronrobertshaw Thanks for the update!
Just to be sure, it's possible that CSS defined at the global style and block instance level will be output with different selectors.
As a result, custom styles defined at the global level may not be overridden at the block instance level.
For example, if you write CSS like color: red; or color: blue; in a Button block, the selector will be different, as shown below:
// Custom CSS added in global styles. Since `selectors.root` is
// taken into account, the a element inside is targeted.
:root :where(.wp-block-button .wp-block-button__link) {
color: red;
}
// Custom CSS added at the block instance level. `selectors.root`
// is not taken into account, so the block wrapper is targeted.
:root :where(.wp-custom-css-60f52167) {
color: blue;
}
// As a result, the button remains red.Is this intended behavior? Should this be fixed in a follow-up?
| } | ||
| ``` | ||
|
|
||
| As an object with a `root` key: |
There was a problem hiding this comment.
Is the reason CSS fields support objects to be consistent with the structure of other selectors?
There was a problem hiding this comment.
Yes, primarily for consistency.
I get the feeling we might need to expand the scope of the Selectors API in the future so being consistent helps that and makes it easier to support differing selectors for the Custom CSS feature if it ends up with subfeatures.
That's definitely the case. Normally, global styles will target a selector and the block supports will be inline styles. There is the exception of preset classes which generally rely on
I'll have to dig into this to confirm there's no issue but both those styles have the same specificity for their selectors due to the wrapping If the recently added Custom CSS for block instances (#73959) didn't correctly output the block instance styles in after Global Styles, that would be a problem. It isn't something that would be caused by this PR or the change of selectors at all though. |
shimotmk
left a comment
There was a problem hiding this comment.
I think the change is a good one.
Changing the root will change the selectors for all other block support, so be careful.
I wish I could test it somehow, but I can't think of a good way to do it. 😅
|
Thanks for the reviews everyone, I'll get this merged 🙇
I'm not sure I follow this, sorry. The Custom CSS feature was already using the root selector, so yes, changing the root selector would change the selector used for the block's custom css. This PR wouldn't change that. This PR allows a block to define a custom selector for the Custom CSS feature. A block type would only define this selector when it was desired so again, I'm not sure what the issue is. |
Related:
What?
When a block type defines a
cssfeature selector in itsblock.jsonselectorsconfig, the Global Styles custom CSS output should honor that selector instead of always using the block's root selector.Why?
Block types can define granular selectors for different style features via the
selectorsproperty inblock.json. For example, a block might define separate selectors forborder,color,typography, etc. The Global Styles system already respects these feature-specific selectors when generating CSS for standard style properties.However, when generating CSS for per-block-type "Additional CSS" (the
cssproperty instyles.blocks.<blockName>.csswithin theme.json / Global Styles), the system always used the block's root selector, ignoring anyselectors.cssconfiguration. This meant blocks had no way to control where their custom CSS was scoped.How?
PHP (
lib/class-wp-theme-json-gutenberg.php)get_styles_for_block(): When processing custom CSS rules (step 7), check$block_metadata['selectors']['css']for a feature-specific selector before falling back to the block's root$selector.get_feature_declarations_for_node(): Skip thecsskey when iterating over feature selectors. Without this, the method would consumecssas a regular style feature — attempting to generate style declarations from the raw CSS string and then deleting$node['css']— which prevented the custom CSS processing in step 7 from ever running.JS (
packages/global-styles-engine/src/core/render.tsx)generateGlobalStyles(): When looping through blocks to process custom CSS, checkfeatureSelectors?.cssbefore falling back to the block's root.selector.All three changes fall back to the root selector when no
cssfeature selector is defined, preserving existing behavior for all current blocks.Testing Instructions
selectors.cssproperty, so there is no user-facing change.color: readinto the Additional CSS field of the icon block's Global Styles. Then check the selector of style created for this.