-
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
Global Styles: consider loading user styles after theme styles #34141
Comments
Potential fix for this issue in #34147 |
👋 Would like to understand what's the issue you're experiencing. The styles are enqueued as they are expected: first the core styles (block-library, global styles), then the theme styles. This has been always like this and the introduction of global styles respected this order. It's intentional, so the theme can overwrite the core styles just by being enqueued later (no extra specificity required). |
It'd be helpful if "how to reproduce" instructions were posted in this issue for people that are not aware of how to work with a theme like BlockBase. I've struggled a bit to make it work. For reference, this is what I've done after some trial&error:
Now, the testing instructions:
The expected result is that user-provided styles should be reflected in the site editor & front-end. They're not. This is what I see: the reason why the user styles are not applied is that the theme overrides them. This is what BlockBase is doing:
.wp-block-button.wp-block-button__link, .wp-block-button .wp-block-button__link {
color: var(--wp--custom--button--color--text);
background-color: var(--wp--custom--button--color--background);
} Why does BlockBase need to provide a stylesheet that overrides the styles already set via its own |
@nosolosw thank you for the thoughtful reply. Apologies for not providing better testing instructions or rationale for why this change could be useful. My general assumption was that if a user makes a customization via global styles UI, it should always win / override the theme's preferences.
The short answer is, we shouldn't be. The principle behind blockbase is that CSS should only exist where theme.json does not supply a way to style the block or element. But in the case of the button block, there are a few places that rule falls apart a bit:
All that said, I think we can close this issue; it can be resolved mostly in Blockbase by removing the theme.json configurable CSS for the button block, and I don't think the use cases described above justify changing the loading order. |
Thanks for sharing the extra context, it's very valuable to me: it shows me practical cases in which the This is what I hear:
I don't have answers yet, but distilling this feedback for our future selves will help us get there. |
I keep thinking about the order of styles. I do think the current order of styles is correct as far as core and theme styles go:
However, there's the gray area of user styles that will be introduced with the site editor. I've been operating under the assumption that user styles provided via the GS sidebar would also be part of the
@jffng Would this approach help address the issue with padding & border? Or would it be more problematic as user styles would have higher priority by being later in the chain? |
At #34196 I've shared an idea that could be helpful for the issue with buttons. |
Yes! I think this is what was happening exactly in this case. Whatever the user changes should take precedence over what the theme initially offers. |
Yes I think so. We want to provide a default for the button padding that combines a border and padding value, which we need to do via CSS. But we can't lower the specificity of the theme CSS so that global styles inline CSS will win if the user has set a preference here. It gets a bit complicated by the "outline" block style variation, but maybe that's a separate issue. Going to re-open this for a bit in case other folks want to add to the discussion. |
Makes sense to me, thanks for reopening. Would you mind also updating the issue description to reflect the idea of separating global styles (core, theme) and global styles (user)? |
I had posted on wordpress forum regarding this issue https://wordpress.org/support/topic/how-to-enqueue-stylesheet-before-block-library-style/ , enqueue and dequeue not work with style tags added by wordpress, so I can't replace it after my bootstrap.css file, I want to keep bootstrap.css load first then the wodpress style tags, so that theme.json default css overwrite bootstrap, currently no way to change order of css loading, or may be there is some way but I am not aware about that ? |
Hey @jffng and @MaggieCabrera I've looked at this and wanted to share my findings. So, as I see this, the theme wants to maintain linked CSS values, which is challenging upon user changes. For example: how to maintain the height of the button (padding+border) for different statuses (rest state, hover state). Let's run with some code. This is the setup: a post with a button (default state, no style variation attached, which is a different issue). In the hover state, the design needs to change colors and the button gains a border it does not have on the rest state. I've tested with the empty theme. Added these styles to its "styles": {
"blocks": {
"core/button": {
"color": {
"background": "hotpink",
"text": "yellow"
},
"spacing": {
"padding": "1em"
}
}
}
} And then to target the hover state, added the following CSS to its stylesheet: .wp-block-button__link:hover {
background-color: yellow;
color: hotpink;
padding: .8em; /* Reduced padding from the rest state */
border: .2em hotpink solid; /* It gains a border it didn't have */
} This works fine: the button keeps the height on hover. What happens when the user changes the padding via the global styles sidebar? The height of the button in the rest and hover states will be different. The reason is that the hover state (custom CSS) doesn't have access to the new height target. This can be tested by going to the site editor and changing the padding of the button block. Would this be solved if we split user styles to a different stylesheet? No, the issue will be the same (height is not maintained). Potential fix What if the theme made the link between those values (padding & border) explicit? Something like this would work:
.wp-block-button__link:hover {
color: hotpink;
background-color: yellow;
padding: calc(var(--wp--theme--button-padding)*0.8);
border: calc(var(--wp--theme--button-padding)*0.2) hotpink solid;} Note the new
We want this result: :root {
--wp--theme--buton-padding: <this comes from the theme.json>
} Which can be achieved by adding a few lines of code to the existing function to enqueue the custom styles: function emptytheme_scripts() {
// Enqueue theme stylesheet, that contains the hover status styles.
wp_register_style( 'emptytheme-style', get_template_directory_uri() . '/style.css', array(), wp_get_theme()->get( 'Version' ) );
// THE NEW CODE.
// Take the value of the target height and inline it as --wp--theme--button-padding.
$value = gutenberg_get_global_styles( array( 'spacing', 'padding' ), 'core/button' );
if ( is_array( $value ) ) { // User values come as an array.
$value = $value['top'];
}
$output = ':root { --wp--theme--button-padding: ' . $value . '; }';
wp_add_inline_style( 'emptytheme-style', $output );
// END OF NEW CODE.
wp_enqueue_style( 'emptytheme-style' );
}
add_action( 'wp_enqueue_scripts', 'emptytheme_scripts' ); This is the gist of it. Note that this is a simplification, as the padding values (top, right, bottom, left) can be different, etc. It's just a sample to show the idea. |
I'm inclined to close this issue. I don't see uses cases that would be fixed from splitting global styles into theme and user. The fact there are some states of the block that aren't absorbed yet via Note that there may be other issues that can be fixable right now. For example, I've just run into a specificity issue in which the outline variation styles override theme.json styles that I'm fixing at #35968 I'd appreciate some help to land that one. Thoughts? |
@oandregal on a quick look that looks like the best solution, we are all in for having a CSS variable that we can play with that keeps the user changes. But I'm thinking this will break if those changes are done on a per-block basis instead of in the global styles. |
Would you expand a bit on what you mean by this? I'm not sure I follow. |
if I user changes the padding of a specific button (instead of all of them in global styles), the hover effect of that button will not respect the height. |
In this case, won't the hover effect be ignored because the padding values are in-lined and will override any padding values of the hover CSS, so it's not an issue?
👍 I think we can close this one too, thanks for explaining and providing some sample code. I understand your suggestion, although I do wish the theme wouldn't have to add such code to enable coordination among style values. If we encounter some use cases where it is useful to separate the user styles from global, we can re-open. |
this should have been no discussion and is nothing to not understand. user customisation always last. I see a question is "what is a user customisation?": eg. Theme Builder adjustments by "user" (/editor) should override theme pre-styling. but Site Editor "customisation" is basically building the site styling, that can all be before theme styling. |
Description
Currently styles load in the following order:
global-styles-inline-css
For example, this is from emptytheme:
This loading order can cause unexpected behavior when the theme wants to specify some defaults that are not entirely possible via theme.json, but still allow for user styles to take precedence. For an example of where this can create unexpected behavior, see Automattic/themes#4435
What is your proposed solution?
Within global styles, it could be useful to separate user styles from the core + theme.json styles. This way, the loading order could be:
The text was updated successfully, but these errors were encountered: