Skip to content
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

Move custom css to its own inline style generation method and combine with customizer CSS #47396

Merged
merged 7 commits into from
Jan 31, 2023

Conversation

glendaviesnz
Copy link
Contributor

@glendaviesnz glendaviesnz commented Jan 25, 2023

What?

Moves global styles custom CSS to its own methods so its position in the output can be modified independently to the other global styles

Why?

This allows the global styles custom CSS to be loaded after any Customizer custom CSS that may have been added in hybrid themes, otherwise this CSS has higher specificity.

How?

Extract the loading of custom CSS into its own method, separate to the other global styles, and include any customizer CSS first in this output.

Testing Instructions

  • Add some custom CSS in global styles, including some block level custom CSS
  • Load in front end and make sure styles appear at the bottom of the global-styles-inline-css style element
  • In a hybrid theme like BlocksBase also add some custom CSS in Customizer and make sure this CSS loads before the Global Style custom CSS in the global-styles-inline-css style element

Screenshots or screencast

Before:
Screenshot 2023-02-01 at 10 34 49 AM

After:

Screenshot 2023-02-01 at 10 32 45 AM

@glendaviesnz glendaviesnz self-assigned this Jan 25, 2023
@glendaviesnz glendaviesnz added the Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json label Jan 25, 2023
@glendaviesnz
Copy link
Contributor Author

glendaviesnz commented Jan 25, 2023

@Mamaduka some of the feedback from custom CSS testing was that it is loading in a different place to the customizer custom CSS.

Getting it to the bottom of the header would require pulling it out into its own method - something like in this draft PR.

What are your thoughts on this? Can you think of a better way?

A couple of things to think about if we go with this approach:

  1. Do we also pull the block specific custom CSS into this?
  2. Do we need to worry about caching this?

@github-actions
Copy link

github-actions bot commented Jan 25, 2023

Flaky tests detected in 3b44904.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4053838918
📝 Reported issues:

@Mamaduka
Copy link
Member

@glendaviesnz, it would be hard to ensure that Custom CSS styles are always loaded last. In block themes, global styles are loaded in the footer, so Custom CSS loaded in the header can be overridden by global styles.

@aristath, you've worked on style loading before. Do you have any suggestions?

@glendaviesnz
Copy link
Contributor Author

glendaviesnz commented Jan 25, 2023

it would be hard to ensure that Custom CSS styles are always loaded last. In block themes, global styles are loaded in the footer, so Custom CSS loaded in the header can be overridden by global styles.

@Mamaduka I probably wasn't clear in my description, ie. rather than ensuring it loads 'absolutely last' the intention is to at least make it load after the majority of other core styles, and particularly to load after the existing customizer custom CSS so it overrides any custom CSS that may have been added there in hybrid themes. The priority of 102 is one lower than the customizer CSS.

I think this is the best we can do, or should try to do. If people still have any problems with the specificity of custom CSS they should just increase the specificity of the selectors they are using.

@Mamaduka
Copy link
Member

ie. rather than ensuring it loads 'absolutely last' the intention is to at least make it load after the majority of other core styles.

Right, that should be our goal.

Currently, hybrid themes shouldn't have access to global styles. How can add "Additional CSS" in Global Styles that conflicts with the customizer?

@glendaviesnz
Copy link
Contributor Author

Currently, hybrid themes shouldn't have access to global styles. How can add "Additional CSS" in Global Styles that conflicts with the customizer?

I was surprised to see that hybrid themes, like BlockBase, get both Customizer and Global styles access. Is that not supposed to be the case? If not then we probably need another PR to sort that as a separate issue to the load order.

@Mamaduka
Copy link
Member

BlockBase is a block theme that uses Customizer, but I don't know if I would call it a hybrid theme. This is the line that enables Customizer backward compatibility - https://github.com/Automattic/themes/blob/trunk/blockbase/inc/customizer/wp-customize-colors.php#L8.

Personally, I think these are rare cases, and we should discourage using both custom CSS options together.

@glendaviesnz
Copy link
Contributor Author

Personally, I think these are rare cases, and we should discourage using both custom CSS options together.

Yeh, in that case probably not worth worrying about anything for 6.2 at least - there is an easy fix for someone confused about the interaction of styles in both places, ie. just use one or the other.

@carolinan
Copy link
Contributor

carolinan commented Jan 25, 2023

It is not that easy to discourage use of both customizer and the site editor. Many plugins add options that enables the Customizer, (and they have to, if they need their options to work with both types of themes).

@Mamaduka
Copy link
Member

@carolinan, that's true. But if you use both Customizer and Editor Custom CSS settings, one of them will be broken.

@carolinan
Copy link
Contributor

I wish we could find a way for them to match before it is too late and people have CSS in both places.

@richtabor
Copy link
Member

It is not that easy to discourage use of both customizer and the site editor.

This is more about discouraging the use of custom CSS in both places.

But if you use both Customizer and Editor Custom CSS settings, one of them will be broken.

What's broken? Is it that both could have competing CSS, where one would overwrite the other?

If we think it's a big enough problem, we could add a reference to the new Additional CSS panel in the Site Editor within the Customizer, though I'm not sure how necessary it is:

CleanShot 2023-01-25 at 14 43 35

@glendaviesnz glendaviesnz marked this pull request as ready for review January 25, 2023 21:42
…rder to get the output in the correct place after the customizer css
$custom_css = get_global_styles_custom_css();
$is_block_theme = wp_is_block_theme();
if ( $custom_css && $is_block_theme ) {
?>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outputting the style element here, instead of using wp_enqueue_style was the only way I could get this to load in the header after the customizer custom CSS - there may be a better approach that I am overlooking

@glendaviesnz
Copy link
Contributor Author

@Mamaduka, @carolinan - this PR now pulls out global and block-level custom CSS into its own style element at the end of the header, so it now matches the placement of the customizer custom CSS.

@Mamaduka
Copy link
Member

What's broken? Is it that both could have competing CSS, where one would overwrite the other?

Correct. What do we gain from fixing this when the user still can have competing CSS while using both Additional CSS settings?

Should we shelve this issue until WP 6.3 and see the feedback?

@glendaviesnz
Copy link
Contributor Author

Should we shelve this issue until WP 6.3 and see the feedback?

@Mamaduka This PR is more about making sure that the new global styles custom CSS is loaded in a similar position in the header as the customizer CSS so that it behaves in a similar way for anyone that is familiar with the customizer, so I think this is worth getting into 6.2.

I agree though that we shouldn't worry about trying to resolve the fact that some themes/plugins might end up with customizer and site editor custom CSS inputs for 6.2, that can wait until after 6.2 and see what feedback there is in relation to that I think.

@aristath
Copy link
Member

Regarding the conflict between custom-css in the customizer and global styles:
It's not an insurmountable problem. It's easy to get the custom-css from the customizer, inject it in global-styles (to solve any backwards-compatibility issues in case the user has added CSS in both places), and then hide the customizer option.
The code below does just that (tested and confirmed)

add_action( 'wp', function() {

	// Bail early if not a block theme.
	if ( ! wp_is_block_theme() ) {
		return;
	}

	// Get the custom CSS from the custom-css post (legacy, customizer).
	$custom_css = wp_get_custom_css();

	// Bail early if there is no custom CSS.
	if ( empty( $custom_css ) ) {
		return;
	}

	// Get the global-styles post.
	$global_styles_post = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( wp_get_theme(), true );
	$global_styles      = json_decode( $global_styles_post['post_content'], true );

	// Ensure we have styles.css in global-styles.
	$global_styles['styles']        = ( empty( $global_styles['styles'] ) ) ? array() : $global_styles['styles'];
	$global_styles['styles']['css'] = ( empty( $global_styles['styles']['css'] ) ) ? '' : $global_styles['styles']['css'];

	// Append the customizer custom-css to the global-styles custom-css.
	$global_styles['styles']['css'] .= $custom_css;

	// Update global-styles.
	wp_update_post( array(
		'ID'           => $global_styles_post['ID'],
		'post_content' => wp_json_encode( $global_styles ),
	) );

	// Remove custom-css.
	wp_update_custom_css_post( '' );
} );

// Remove the "Custom CSS" section from the customizer.
add_action( 'customize_register', function( $wp_customize ) {
	$wp_customize->remove_section( 'custom_css' );
}, 999 );

Notes: The above code runs on the wp action which is wrong as it requires us to visit the frontend in order for the migration to run (it doesn't run in the site-editor). But that's a minor thing we can easily solve with some experimentation.

The code above does the following:

  • Check if it's a block theme. If not, don't do anything.
  • Check if we have legacy custom-css in the customizer. If not, don't do anything.
  • Append the legacy custom-css to the global-styles custom-css
  • Delete the legacy custom-css
  • Remove the custom-css section from the customizer.

It's simple and it works.

@glendaviesnz
Copy link
Contributor Author

Thanks @aristath - that looks pretty straightforward. I don't have a strong opinion on whether we try to get something like that into 6.2, but either way, I think we should keep it separate from this PR.

@aristath
Copy link
Member

aristath commented Jan 26, 2023

Agreed. Just pointing out that we should not consider the customizer legacy implementation a blocker for any improvements we make. These problems can be solved with some additional code 👍

@Mamaduka
Copy link
Member

@glendaviesnz, I've got an alternative idea inspired by @aristath's comment. I will try to test it and share it as soon as possible.

@glendaviesnz
Copy link
Contributor Author

@Mamaduka how did you get on with your alternative PR for this? If that is not ready yet should we go with this approach for 15.1/6.2 and follow up with your one later?

@Mamaduka
Copy link
Member

Sorry for the delay, @glendaviesnz. Here's my alternative method; it can be directly merged into this PR - #47554.

* Update enqueuing method
* Minor updates to get_global_styles_custom_css
* Always return string
@glendaviesnz
Copy link
Contributor Author

Thanks @Mamaduka & @aristath for merging that change, that is a better approach I think. This is testing well for me now and global styles custom CSS is output after the other global styles and after any customizer custom CSS.

@glendaviesnz glendaviesnz changed the title Move custom css to its own inline style at bottom of header Move custom css to its own inline style generation method and combine with customizer CSS Jan 31, 2023
@apeatling apeatling self-requested a review January 31, 2023 22:05
Copy link
Contributor

@apeatling apeatling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed that:

✅ Styles in the block editor added to the site level appear at the bottom of the inlineglobal-styles-inline-css.
✅ Styles in the block editor added to the block level appear at the bottom of the inline global-styles-inline-css.
✅ Styles added in the Customizer appear before the styles added in the block editor at the bottom of global-styles-inline-css when using the Blockbase theme.

In block editor:

Screenshot 2023-01-31 at 2 08 35 PM

Screenshot 2023-01-31 at 2 08 48 PM

In Customizer:

Screenshot 2023-01-31 at 2 09 59 PM

Bottom of global-styles-inline-css in Blockbase theme:

Screenshot 2023-01-31 at 2 05 33 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json Needs User Documentation Needs new user documentation [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants