Make WordPress Core

Opened 2 years ago

#57091 assigned defect (bug)

Global Styles: Element styles not working for third-party blocks

Reported by: ehtmlu's profile ehtmlu Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.1
Component: Editor Keywords:
Focuses: Cc:

Description

This is a follow-up to #56915.

The Problem:

Element-specific global styles for third-party blocks still don't work. The styles are not added to the inline CSS in the frontend.


General global styles for third-party blocks work well:

{
    "$schema": "https://schemas.wp.org/trunk/theme.json",
    "version": 2,
    "styles": {
        "blocks": {
            "my/third-party-block": {
                "color": {
                    "background": "hotpink"
                }
            }
        }
    }
}

✔ work well in the block editor
✔ work well in the frontend


Element-specific global styles for third-party blocks don't work:

{
    "$schema": "https://schemas.wp.org/trunk/theme.json",
    "version": 2,
    "styles": {
        "blocks": {
            "my/third-party-block": {
                "elements": {
                    "link": {
                        "color": {
                            "background": "hotpink"
                        }
                    }
                }
            }
        }
    }
}

✔ work well in the block editor
❌ don't work in the frontend


Investigation:

Since it works fine in the block editor, I thought it must be unintentional that it doesn't work in the frontend. So I researched deeper and came across the wp_add_global_styles_for_blocks function.

At the end of the function there is this part:

function wp_add_global_styles_for_blocks() {

	...

		// The likes of block element styles from theme.json do not have  $metadata['name'] set.
		if ( ! isset( $metadata['name'] ) && ! empty( $metadata['path'] ) ) {
			$result = array_values(
				array_filter(
					$metadata['path'],
					function ( $item ) {
						if ( strpos( $item, 'core/' ) !== false ) {
							return true;
						}
						return false;
					}
				)
			);
			if ( isset( $result[0] ) ) {
				if ( str_starts_with( $result[0], 'core/' ) ) {
					$block_name        = str_replace( 'core/', '', $result[0] );
					$stylesheet_handle = 'wp-block-' . $block_name;
				}
				wp_add_inline_style( $stylesheet_handle, $block_css );
			}
		}
	}
}

In that part this happens:

  1. With the statement if ( str_starts_with( $result[0], 'core/' ) ) we check whether it is a core block or not. However, because of the array_filter before, the values of $result can only start with core/ anyway. So this if statement is redundant.
  2. So if isset( $result[0] ) is TRUE, it always is a core block. Therefor the function wp_add_inline_style will be called only for core blocks but never for third-party blocks.

Solution:

  • Remove the redundant if ( str_starts_with( $result[0], 'core/' ) ) statement
  • Move the wp_add_inline_style function call outside the if ( isset( $result[0] ) ) statement
    function wp_add_global_styles_for_blocks() {
    
    	...
    
    		// The likes of block element styles from theme.json do not have  $metadata['name'] set.
    		if ( ! isset( $metadata['name'] ) && ! empty( $metadata['path'] ) ) {
    			$result = array_values(
    				array_filter(
    					$metadata['path'],
    					function ( $item ) {
    						if ( strpos( $item, 'core/' ) !== false ) {
    							return true;
    						}
    						return false;
    					}
    				)
    			);
    			if ( isset( $result[0] ) ) {
    				$block_name        = str_replace( 'core/', '', $result[0] );
    				$stylesheet_handle = 'wp-block-' . $block_name;
    			}
    			wp_add_inline_style( $stylesheet_handle, $block_css );
    		}
    	}
    }
    

Change History (0)

Note: See TracTickets for help on using tickets.