Skip to content

Print IMG auto-sizes contain CSS fix by enqueueing inline style#8954

Closed
westonruter wants to merge 10 commits intoWordPress:trunkfrom
westonruter:fix/trac-62731
Closed

Print IMG auto-sizes contain CSS fix by enqueueing inline style#8954
westonruter wants to merge 10 commits intoWordPress:trunkfrom
westonruter:fix/trac-62731

Conversation

@westonruter
Copy link
Copy Markdown
Member

@westonruter westonruter commented Jun 10, 2025

Trac ticket: https://core.trac.wordpress.org/ticket/62731

Instead of manually printing the STYLE tag to fix sizes=auto issue with images, this enqueues the inline style via WP_Styles. This ensures the styles are printed with other styles as opposed to being printed very early, even before the TITLE tag. This also allows plugins to do additional processing of the stylesheet prior to it being printed. Note that array_unshift( wp_scripts()->queue, $handle ) is used instead of wp_enqueue_style( $handle ) in order to ensure that the stylesheet is printed before any others, preserving the existing cascade.

This is very similar to the change that was made to replace print_emoji_styles() with wp_enqueue_emoji_styles() in Core-58775.

Diff on rendered page (after Prettier formatting):

--- /tmp/before.html	2025-06-10 16:25:19
+++ /tmp/after.html	2025-06-10 16:25:39
@@ -4,11 +4,6 @@
 		<meta charset="UTF-8" />
 		<meta name="viewport" content="width=device-width, initial-scale=1" />
 		<meta name="robots" content="max-image-preview:large" />
-		<style>
-			img:is([sizes='auto' i], [sizes^='auto,' i]) {
-				contain-intrinsic-size: 3000px 1500px;
-			}
-		</style>
 		<title>WordPress Develop</title>
 		<link
 			rel="alternate"
@@ -544,6 +539,11 @@
 				}
 			)(window, document, window._wpemojiSettings);
 		</script>
+		<style id="wp-img-auto-sizes-contain-inline-css">
+			img:is([sizes='auto' i], [sizes^='auto,' i]) {
+				contain-intrinsic-size: 3000px 1500px;
+			}
+			/*# sourceURL=wp-img-auto-sizes-contain-inline-css */
+		</style>
 		<style id="wp-block-site-title-inline-css">
 			.wp-block-site-title {
 				box-sizing: border-box;

This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@westonruter westonruter marked this pull request as draft June 10, 2025 23:33
@github-actions
Copy link
Copy Markdown

github-actions bot commented Jun 10, 2025

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 props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props westonruter, joemcgill, flixos90.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions
Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • The Plugin and Theme Directories cannot be accessed within Playground.
  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

wp_add_inline_style( $handle, 'img:is([sizes="auto" i], [sizes^="auto," i]) { contain-intrinsic-size: 3000px 1500px }' );

// Make sure inline style is printed first.
array_unshift( wp_styles()->queue, $handle );
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This seems a bit hacky to me, but I understand the purpose. I assume there's not a better way to control the order of registered styles besides maybe making sure that the wp_register_style() call is made on an earlier hook, like init, correct?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Exactly.

* @link https://html.spec.whatwg.org/multipage/rendering.html#img-contain-size
* @link https://core.trac.wordpress.org/ticket/62413
*/
function wp_print_auto_sizes_contain_css_fix() {
Copy link
Copy Markdown
Member

@felixarntz felixarntz Jun 11, 2025

Choose a reason for hiding this comment

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

I don't love this name now, since it's implying this function does something that it doesn't.

We could potentially deprecate (effectively rename) it, though let's discuss how reasonable that would be.

  • Obviously there's a BC risk if people expect this function to be hooked into wp_head and want to remove it to disable the snippet.
  • However, there's also a BC risk if we just change what this function does, in case someone calls it manually somewhere else.
  • If someone unhooks this function to disable the snippet, and we wanted to replace it with a new function, we could still add the hook first, see if it is removed, and only before the function would be called ensure it is not invoked. This way we know whether it was removed, and could "forward" this removal to the new function.
    • I believe we did something like that in Core somewhere else before, but I can't recall where exactly.
  • A nice side-effect of deprecating / replacing would be that we could also use the proper hook wp_enqueue_scripts for the new function.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@felixarntz see e7144a3 for that which was the original approach I took.

I believe we did something like that in Core somewhere else before, but I can't recall where exactly.

Yes. We did it with printing the emoji styles in Core-58775.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member Author

@westonruter westonruter Jun 12, 2025

Choose a reason for hiding this comment

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

If we go with the function rename and move from wp_head to wp_enqueue_scripts, since this function was introduced with the wp_img_tag_add_auto_sizes filter to disable the style, it seems overkill to also retain back-compat to see if someone removed the action on wp_head. If they had done this, they were essentially doing it wrong. There are only 4 examples of this being done on GitHub.

Update: The wp_img_tag_add_auto_sizes filter doesn't just prevent the style from being printed. It also omits sizes=auto from the IMG tags as well. See #8954 (comment)

Copy link
Copy Markdown
Member Author

@westonruter westonruter Jun 12, 2025

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@felixarntz I believe your concerns are addressed by introducing a separate function here. If so, please approve the PR.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

After re-examining the purpose of the wp_img_tag_add_auto_sizes filter, I realize I was wrong to suggest that it was the right way to prevent the style from being printed. See #8954 (comment)

@westonruter westonruter marked this pull request as ready for review June 12, 2025 19:42
@westonruter westonruter requested a review from felixarntz June 13, 2025 00:35
@westonruter
Copy link
Copy Markdown
Member Author

I just merged in the latest from trunk. Note there is now a sourceURL comment present:

<style id='wp-img-auto-sizes-contain-inline-css'>
img:is([sizes="auto" i], [sizes^="auto," i]) { contain-intrinsic-size: 3000px 1500px }
/*# sourceURL=wp-img-auto-sizes-contain-inline-css */
</style>

* @see https://core.trac.wordpress.org/ticket/62413
*/
function wp_print_auto_sizes_contain_css_fix() {
function wp_enqueue_img_auto_sizes_contain_css_fix(): void {
Copy link
Copy Markdown
Member

@felixarntz felixarntz Oct 2, 2025

Choose a reason for hiding this comment

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

Shouldn't we, either within this function, or in some other logic that runs on a hook shortly before this, check for has_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix' ), and only remove the deprecated action at the point that we know it wasn't intentionally removed by any 3P code?

I think we should include this for BC, to make sure sites that removed the original hook don't see adverse effects now because we changed the hook. This is similar to how we did it elsewhere before I think.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@felixarntz Thanks for raising this again. After re-examining the purpose of the wp_img_tag_add_auto_sizes filter, I realize I was wrong to suggest that it was the right way to prevent the style from being printed. See #8954 (comment)

westonruter and others added 2 commits October 2, 2025 20:06
Co-authored-by: Felix Arntz <flixos90@git.wordpress.org>
@westonruter
Copy link
Copy Markdown
Member Author

In 67d527c I've addressed the concerns with backwards-compatibility with themes/plugins that have intended to prevent this style from being printed by unhooking the action via:

remove_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', 1 );

In looking at this further, I realize I was mistaken in thinking that the wp_img_tag_add_auto_sizes was how this style was actually supposed to be omitted. In reality, this filter does much more, as it prevents sizes=auto from being added to all images as well. Therefore, I was wrong to suggest the proper way to simply omit this style was to do add_filter( 'wp_img_tag_add_auto_sizes', '__return_false' ).

In order to maintain backwards-compatibility, the now-deprecated wp_print_auto_sizes_contain_css_fix() function now remains hooked at wp_head with a priority 1, and now the wp_enqueue_img_auto_sizes_contain_css_fix() function is hooked at wp_head with priority 0, just before wp_print_auto_sizes_contain_css_fix() is slated to run. The first thing that wp_print_auto_sizes_contain_css_fix() does is it checks to see if has_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix' ). If not, then it short-circuits. Otherwise, it goes ahead and removes the action to prevent the deprecation notice, while also proceeding with enqueueing the CSS fix.

I've added tests for these various scenarios.

@westonruter westonruter requested a review from felixarntz October 3, 2025 03:24
Copy link
Copy Markdown
Member

@felixarntz felixarntz left a comment

Choose a reason for hiding this comment

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

@westonruter Thank you for the updates, looks good to go IMO!

pento pushed a commit that referenced this pull request Oct 7, 2025
…` tags having `sizes=auto`.

This deprecates the `wp_print_auto_sizes_contain_css_fix()` function running at `wp_head` priority 1, in favor of a `wp_enqueue_img_auto_sizes_contain_css_fix()` function which runs just before at `wp_head` priority 0. The latter function unhooks the former while also enqueueing an inline style to be printed with all other styles but up front to preserve the cascade. This eliminates directly printing the `STYLE` tag, which was a change done similarly before for the emoji styles. See #58775.

For backwards compatibility, the CSS can still be prevented from being enqueued/printed via:

    remove_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', 1 );

This change ensures that all styles are printed together using the correct API for emitting styles.

Developed in #8954.

Follow-up to [59435].

Props westonruter, sabernhardt, SirLouen, flixos90, joemcgill, SergeyBiryukov, superpoincare.
See #62413.
Fixes #62731.


git-svn-id: https://develop.svn.wordpress.org/trunk@60910 602fd350-edb4-49c9-b593-d223f7449a82
@github-actions
Copy link
Copy Markdown

github-actions bot commented Oct 7, 2025

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 60910
GitHub commit: 2ffca40

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions bot closed this Oct 7, 2025
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Oct 7, 2025
…` tags having `sizes=auto`.

This deprecates the `wp_print_auto_sizes_contain_css_fix()` function running at `wp_head` priority 1, in favor of a `wp_enqueue_img_auto_sizes_contain_css_fix()` function which runs just before at `wp_head` priority 0. The latter function unhooks the former while also enqueueing an inline style to be printed with all other styles but up front to preserve the cascade. This eliminates directly printing the `STYLE` tag, which was a change done similarly before for the emoji styles. See #58775.

For backwards compatibility, the CSS can still be prevented from being enqueued/printed via:

    remove_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', 1 );

This change ensures that all styles are printed together using the correct API for emitting styles.

Developed in WordPress/wordpress-develop#8954.

Follow-up to [59435].

Props westonruter, sabernhardt, SirLouen, flixos90, joemcgill, SergeyBiryukov, superpoincare.
See #62413.
Fixes #62731.

Built from https://develop.svn.wordpress.org/trunk@60910


git-svn-id: http://core.svn.wordpress.org/trunk@60246 1a063a9b-81f0-0310-95a4-ce76da25c4cd
github-actions bot pushed a commit to platformsh/wordpress-performance that referenced this pull request Oct 7, 2025
…` tags having `sizes=auto`.

This deprecates the `wp_print_auto_sizes_contain_css_fix()` function running at `wp_head` priority 1, in favor of a `wp_enqueue_img_auto_sizes_contain_css_fix()` function which runs just before at `wp_head` priority 0. The latter function unhooks the former while also enqueueing an inline style to be printed with all other styles but up front to preserve the cascade. This eliminates directly printing the `STYLE` tag, which was a change done similarly before for the emoji styles. See #58775.

For backwards compatibility, the CSS can still be prevented from being enqueued/printed via:

    remove_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', 1 );

This change ensures that all styles are printed together using the correct API for emitting styles.

Developed in WordPress/wordpress-develop#8954.

Follow-up to [59435].

Props westonruter, sabernhardt, SirLouen, flixos90, joemcgill, SergeyBiryukov, superpoincare.
See #62413.
Fixes #62731.

Built from https://develop.svn.wordpress.org/trunk@60910


git-svn-id: https://core.svn.wordpress.org/trunk@60246 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants