From 2b0405eebc15609c93137c5f83915e1fb245b173 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Wed, 8 Jul 2026 14:06:58 +1000 Subject: [PATCH 1/5] Enable default gap processing on Gallery block --- packages/block-library/src/gallery/README.md | 2 +- packages/block-library/src/gallery/block.json | 6 ++++-- packages/block-library/src/gallery/gap-styles.js | 10 +--------- packages/block-library/src/gallery/index.php | 12 ++++-------- 4 files changed, 10 insertions(+), 20 deletions(-) diff --git a/packages/block-library/src/gallery/README.md b/packages/block-library/src/gallery/README.md index 165ba870be28bf..7a09359acaba2f 100644 --- a/packages/block-library/src/gallery/README.md +++ b/packages/block-library/src/gallery/README.md @@ -47,7 +47,7 @@ _Defined via the [`supports`](https://developer.wordpress.org/block-editor/refer - [`spacing`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#spacing): - `margin`: `true` - `padding`: `true` - - `blockGap`: `["horizontal","vertical"]` + - `blockGap`: `{"sides":["horizontal","vertical"],"__experimentalDefault":"var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )"}` - [`color`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color): - [`text`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color-text): `false` - [`background`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color-background): `true` diff --git a/packages/block-library/src/gallery/block.json b/packages/block-library/src/gallery/block.json index 0d63ad7332b480..1c539217579189 100644 --- a/packages/block-library/src/gallery/block.json +++ b/packages/block-library/src/gallery/block.json @@ -142,8 +142,10 @@ "spacing": { "margin": true, "padding": true, - "blockGap": [ "horizontal", "vertical" ], - "__experimentalSkipSerialization": [ "blockGap" ], + "blockGap": { + "sides": [ "horizontal", "vertical" ], + "__experimentalDefault": "var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )" + }, "__experimentalDefaultControls": { "blockGap": true, "margin": false, diff --git a/packages/block-library/src/gallery/gap-styles.js b/packages/block-library/src/gallery/gap-styles.js index a1ad61f02b9955..f7ee45ee797703 100644 --- a/packages/block-library/src/gallery/gap-styles.js +++ b/packages/block-library/src/gallery/gap-styles.js @@ -10,27 +10,19 @@ export default function GapStyles( { blockGap, clientId } ) { // --gallery-block--gutter-size is deprecated. --wp--style--gallery-gap-default should be used by themes that want to set a default // gap on the gallery. const fallbackValue = `var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )`; - let gapValue = fallbackValue; let column = fallbackValue; - let row; // Check for the possibility of split block gap values. See: https://github.com/WordPress/gutenberg/pull/37736 if ( !! blockGap ) { - row = - typeof blockGap === 'string' - ? getGapCSSValue( blockGap ) - : getGapCSSValue( blockGap?.top ) || fallbackValue; column = typeof blockGap === 'string' ? getGapCSSValue( blockGap ) : getGapCSSValue( blockGap?.left ) || fallbackValue; - gapValue = row === column ? row : `${ row } ${ column }`; } // The unstable gallery gap calculation requires a real value (such as `0px`) and not `0`. const gap = `#block-${ clientId } { - --wp--style--unstable-gallery-gap: ${ column === '0' ? '0px' : column }; - gap: ${ gapValue } + --wp--style--unstable-gallery-gap: ${ column === '0' ? '0px' : column } }`; useStyleOverride( { css: gap } ); diff --git a/packages/block-library/src/gallery/index.php b/packages/block-library/src/gallery/index.php index 4ab641d9233006..58ffeb0b230dcb 100644 --- a/packages/block-library/src/gallery/index.php +++ b/packages/block-library/src/gallery/index.php @@ -385,13 +385,10 @@ function block_core_gallery_render( $attributes, $content, $block ) { // --gallery-block--gutter-size is deprecated. --wp--style--gallery-gap-default should be used by themes that want to set a default // gap on the gallery. $fallback_gap = 'var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )'; - $gap_value = $gap ? $gap : $fallback_gap; - $gap_column = $gap_value; + $gap_column = ( null !== $gap && '' !== $gap ) ? $gap : $fallback_gap; - if ( is_array( $gap_value ) ) { - $gap_row = $gap_value['top'] ?? $fallback_gap; - $gap_column = $gap_value['left'] ?? $fallback_gap; - $gap_value = $gap_row === $gap_column ? $gap_row : $gap_row . ' ' . $gap_column; + if ( is_array( $gap_column ) ) { + $gap_column = $gap_column['left'] ?? $fallback_gap; } // The unstable gallery gap calculation requires a real value (such as `0px`) and not `0`. @@ -399,13 +396,12 @@ function block_core_gallery_render( $attributes, $content, $block ) { $gap_column = '0px'; } - // Set the CSS variable to the column value, and the `gap` property to the combined gap value. + // Set the CSS variable to the column value for Gallery's flex width calculations. $gallery_styles = array( array( 'selector' => ".wp-block-gallery.{$unique_gallery_classname}", 'declarations' => array( '--wp--style--unstable-gallery-gap' => $gap_column, - 'gap' => $gap_value, ), ), ); From e4613289e6a849d1f1dff1c3addb32be469ac794 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Wed, 8 Jul 2026 14:48:48 +1000 Subject: [PATCH 2/5] ensure gap value in width calculation is always correct --- package-lock.json | 1 + packages/block-library/package.json | 1 + packages/block-library/src/gallery/edit.js | 5 +- .../block-library/src/gallery/gap-styles.js | 54 ++++++-- packages/block-library/src/gallery/index.php | 116 ++++++++++++------ 5 files changed, 122 insertions(+), 55 deletions(-) diff --git a/package-lock.json b/package-lock.json index c88a8110f32830..a4660b08d53c13 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45216,6 +45216,7 @@ "@wordpress/dom": "file:../dom", "@wordpress/element": "file:../element", "@wordpress/escape-html": "file:../escape-html", + "@wordpress/global-styles-engine": "file:../global-styles-engine", "@wordpress/hooks": "file:../hooks", "@wordpress/html-entities": "file:../html-entities", "@wordpress/i18n": "file:../i18n", diff --git a/packages/block-library/package.json b/packages/block-library/package.json index a224510b32422d..fa560e8e14de56 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -108,6 +108,7 @@ "@wordpress/dom": "file:../dom", "@wordpress/element": "file:../element", "@wordpress/escape-html": "file:../escape-html", + "@wordpress/global-styles-engine": "file:../global-styles-engine", "@wordpress/hooks": "file:../hooks", "@wordpress/html-entities": "file:../html-entities", "@wordpress/i18n": "file:../i18n", diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 9d98022490e17b..e3135fc07e8298 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -941,10 +941,7 @@ export default function GalleryEdit( props ) { /> ) } - + { isDynamic ? ( { + const viewportBlockGap = style?.[ viewport ]?.spacing?.blockGap; + if ( viewportBlockGap === undefined || viewportBlockGap === null ) { + return; + } + + gap += `${ mediaQuery }{${ getGapStyle( + selector, + viewportBlockGap + ) }}`; + } + ); useStyleOverride( { css: gap } ); diff --git a/packages/block-library/src/gallery/index.php b/packages/block-library/src/gallery/index.php index 58ffeb0b230dcb..51d839f1ed72c7 100644 --- a/packages/block-library/src/gallery/index.php +++ b/packages/block-library/src/gallery/index.php @@ -52,6 +52,54 @@ function block_core_gallery_render_context( $context, $parsed_block ) { add_filter( 'render_block_context', 'block_core_gallery_render_context', 10, 2 ); +/** + * Returns the column gap value used for Gallery image width calculations. + * + * @since 7.1.0 + * + * @param string|array|null $gap Gallery block gap value. + * @param string $fallback_gap Fallback gap value. + * @return string Gallery column gap value. + */ +function block_core_gallery_get_column_gap_value( $gap, $fallback_gap ) { + if ( is_array( $gap ) ) { + $gap = $gap['left'] ?? $fallback_gap; + } + + $gap = is_string( $gap ) ? $gap : ''; + $gap = $gap && preg_match( '%[\\\(&=}]|/\*%', $gap ) ? null : $gap; + + // Get spacing CSS variable from preset value if provided. + if ( is_string( $gap ) && str_contains( $gap, 'var:preset|spacing|' ) ) { + $index_to_splice = strrpos( $gap, '|' ) + 1; + $slug = _wp_to_kebab_case( substr( $gap, $index_to_splice ) ); + $gap = "var(--wp--preset--spacing--$slug)"; + } + + $gap_column = ( null !== $gap && '' !== $gap ) ? $gap : $fallback_gap; + + // The unstable gallery gap calculation requires a real value (such as `0px`) and not `0`. + return '0' === $gap_column ? '0px' : $gap_column; +} + +/** + * Returns configured viewport media queries. + * + * @since 7.1.0 + * + * @param mixed $viewport_settings Viewport settings from theme.json. + * @return array Responsive media queries. + */ +function block_core_gallery_get_viewport_media_queries( $viewport_settings ) { + foreach ( array( 'WP_Theme_JSON_Gutenberg', 'WP_Theme_JSON' ) as $theme_json_class_name ) { + if ( method_exists( $theme_json_class_name, 'get_viewport_media_queries' ) ) { + return $theme_json_class_name::get_viewport_media_queries( $viewport_settings ); + } + } + + return array(); +} + /** * Resolves a Gallery block's `dynamicContent` to an ordered list of image * attachment IDs. @@ -345,36 +393,11 @@ function block_core_gallery_render( $attributes, $content, $block ) { // the current gap setting in order to maintain the number of flex columns // so a css var is added to allow this. - $gap = $attributes['style']['spacing']['blockGap'] ?? null; - // Skip if gap value contains unsupported characters. - // Regex for CSS value borrowed from `safecss_filter_attr`, and used here - // because we only want to match against the value, not the CSS attribute. - if ( is_array( $gap ) ) { - foreach ( $gap as $key => $value ) { - // Make sure $value is a string to avoid PHP 8.1 deprecation error in preg_match() when the value is null. - $value = is_string( $value ) ? $value : ''; - $value = $value && preg_match( '%[\\\(&=}]|/\*%', $value ) ? null : $value; - - // Get spacing CSS variable from preset value if provided. - if ( is_string( $value ) && str_contains( $value, 'var:preset|spacing|' ) ) { - $index_to_splice = strrpos( $value, '|' ) + 1; - $slug = _wp_to_kebab_case( substr( $value, $index_to_splice ) ); - $value = "var(--wp--preset--spacing--$slug)"; - } - - $gap[ $key ] = $value; - } - } else { - // Make sure $gap is a string to avoid PHP 8.1 deprecation error in preg_match() when the value is null. - $gap = is_string( $gap ) ? $gap : ''; - $gap = $gap && preg_match( '%[\\\(&=}]|/\*%', $gap ) ? null : $gap; - - // Get spacing CSS variable from preset value if provided. - if ( is_string( $gap ) && str_contains( $gap, 'var:preset|spacing|' ) ) { - $index_to_splice = strrpos( $gap, '|' ) + 1; - $slug = _wp_to_kebab_case( substr( $gap, $index_to_splice ) ); - $gap = "var(--wp--preset--spacing--$slug)"; - } + $style_attr = is_array( $attributes['style'] ?? null ) + ? $attributes['style'] + : array(); + if ( function_exists( 'gutenberg_resolve_style_state_aliases' ) ) { + $style_attr = gutenberg_resolve_style_state_aliases( $style_attr, 'core/gallery' ); } $unique_gallery_classname = wp_unique_id( 'wp-block-gallery-' ); @@ -385,16 +408,7 @@ function block_core_gallery_render( $attributes, $content, $block ) { // --gallery-block--gutter-size is deprecated. --wp--style--gallery-gap-default should be used by themes that want to set a default // gap on the gallery. $fallback_gap = 'var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )'; - $gap_column = ( null !== $gap && '' !== $gap ) ? $gap : $fallback_gap; - - if ( is_array( $gap_column ) ) { - $gap_column = $gap_column['left'] ?? $fallback_gap; - } - - // The unstable gallery gap calculation requires a real value (such as `0px`) and not `0`. - if ( '0' === $gap_column ) { - $gap_column = '0px'; - } + $gap_column = block_core_gallery_get_column_gap_value( $style_attr['spacing']['blockGap'] ?? null, $fallback_gap ); // Set the CSS variable to the column value for Gallery's flex width calculations. $gallery_styles = array( @@ -406,6 +420,28 @@ function block_core_gallery_render( $attributes, $content, $block ) { ), ); + $global_settings = wp_get_global_settings(); + $viewport_settings = $global_settings['viewport'] ?? null; + $responsive_media_queries = block_core_gallery_get_viewport_media_queries( $viewport_settings ); + + foreach ( $responsive_media_queries as $breakpoint => $media_query ) { + $viewport_style = $style_attr[ $breakpoint ] ?? null; + if ( ! is_array( $viewport_style ) || ! isset( $viewport_style['spacing']['blockGap'] ) ) { + continue; + } + + $gallery_styles[] = array( + 'selector' => ".wp-block-gallery.{$unique_gallery_classname}", + 'declarations' => array( + '--wp--style--unstable-gallery-gap' => block_core_gallery_get_column_gap_value( + $viewport_style['spacing']['blockGap'], + $fallback_gap + ), + ), + 'rules_group' => $media_query, + ); + } + wp_style_engine_get_stylesheet_from_css_rules( $gallery_styles, array( 'context' => 'block-supports' ) From 935ee6b1abab9e7f51be8fe03d53666482a6fbaf Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Wed, 8 Jul 2026 15:18:21 +1000 Subject: [PATCH 3/5] clarify custom property output --- packages/block-library/src/gallery/edit.js | 7 +++++-- .../block-library/src/gallery/gap-styles.js | 17 ++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index e3135fc07e8298..d892b53e90a701 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -66,7 +66,7 @@ import { import useImageSizes from './use-image-sizes'; import useGetNewImages from './use-get-new-images'; import useGetMedia from './use-get-media'; -import GapStyles from './gap-styles'; +import GalleryGapCustomProperties from './gap-styles'; import useDynamicGallery from './use-dynamic-gallery'; import { GallerySourcePanel, GalleryDynamicView } from './dynamic-gallery'; import { getDynamicSource, ATTACHED_MEDIA } from './dynamic-source'; @@ -941,7 +941,10 @@ export default function GalleryEdit( props ) { /> ) } - + { isDynamic ? ( { @@ -50,7 +49,7 @@ export default function GapStyles( { style, clientId } ) { return; } - gap += `${ mediaQuery }{${ getGapStyle( + gap += `${ mediaQuery }{${ getGalleryGapCustomPropertyStyle( selector, viewportBlockGap ) }}`; From f259b878a2644a4dfaf2ecfdbf2d4d977a0cd513 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Wed, 8 Jul 2026 15:24:34 +1000 Subject: [PATCH 4/5] re-add comments and inline function --- packages/block-library/src/gallery/index.php | 31 ++++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/packages/block-library/src/gallery/index.php b/packages/block-library/src/gallery/index.php index 51d839f1ed72c7..7bb2b7b9376644 100644 --- a/packages/block-library/src/gallery/index.php +++ b/packages/block-library/src/gallery/index.php @@ -66,7 +66,12 @@ function block_core_gallery_get_column_gap_value( $gap, $fallback_gap ) { $gap = $gap['left'] ?? $fallback_gap; } + // Make sure $gap is a string to avoid PHP 8.1 deprecation error in preg_match() when the value is null. $gap = is_string( $gap ) ? $gap : ''; + + // Skip if gap value contains unsupported characters. + // Regex for CSS value borrowed from `safecss_filter_attr`, and used here + // because we only want to match against the value, not the CSS attribute. $gap = $gap && preg_match( '%[\\\(&=}]|/\*%', $gap ) ? null : $gap; // Get spacing CSS variable from preset value if provided. @@ -82,24 +87,6 @@ function block_core_gallery_get_column_gap_value( $gap, $fallback_gap ) { return '0' === $gap_column ? '0px' : $gap_column; } -/** - * Returns configured viewport media queries. - * - * @since 7.1.0 - * - * @param mixed $viewport_settings Viewport settings from theme.json. - * @return array Responsive media queries. - */ -function block_core_gallery_get_viewport_media_queries( $viewport_settings ) { - foreach ( array( 'WP_Theme_JSON_Gutenberg', 'WP_Theme_JSON' ) as $theme_json_class_name ) { - if ( method_exists( $theme_json_class_name, 'get_viewport_media_queries' ) ) { - return $theme_json_class_name::get_viewport_media_queries( $viewport_settings ); - } - } - - return array(); -} - /** * Resolves a Gallery block's `dynamicContent` to an ordered list of image * attachment IDs. @@ -422,7 +409,13 @@ function block_core_gallery_render( $attributes, $content, $block ) { $global_settings = wp_get_global_settings(); $viewport_settings = $global_settings['viewport'] ?? null; - $responsive_media_queries = block_core_gallery_get_viewport_media_queries( $viewport_settings ); + $responsive_media_queries = array(); + foreach ( array( 'WP_Theme_JSON_Gutenberg', 'WP_Theme_JSON' ) as $theme_json_class_name ) { + if ( method_exists( $theme_json_class_name, 'get_viewport_media_queries' ) ) { + $responsive_media_queries = $theme_json_class_name::get_viewport_media_queries( $viewport_settings ); + break; + } + } foreach ( $responsive_media_queries as $breakpoint => $media_query ) { $viewport_style = $style_attr[ $breakpoint ] ?? null; From d31efb0793af04ea0809771bb365b9d370086cbb Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Wed, 8 Jul 2026 15:38:39 +1000 Subject: [PATCH 5/5] fix errors --- packages/block-library/src/gallery/index.php | 6 +++++- packages/block-library/tsconfig.json | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/gallery/index.php b/packages/block-library/src/gallery/index.php index 7bb2b7b9376644..fac0c115640928 100644 --- a/packages/block-library/src/gallery/index.php +++ b/packages/block-library/src/gallery/index.php @@ -383,7 +383,11 @@ function block_core_gallery_render( $attributes, $content, $block ) { $style_attr = is_array( $attributes['style'] ?? null ) ? $attributes['style'] : array(); - if ( function_exists( 'gutenberg_resolve_style_state_aliases' ) ) { + if ( + defined( 'IS_GUTENBERG_PLUGIN' ) && + IS_GUTENBERG_PLUGIN && + function_exists( 'gutenberg_resolve_style_state_aliases' ) + ) { $style_attr = gutenberg_resolve_style_state_aliases( $style_attr, 'core/gallery' ); } diff --git a/packages/block-library/tsconfig.json b/packages/block-library/tsconfig.json index 13581ab393bb6e..bb1821a17c5024 100644 --- a/packages/block-library/tsconfig.json +++ b/packages/block-library/tsconfig.json @@ -21,6 +21,7 @@ { "path": "../dom" }, { "path": "../element" }, { "path": "../escape-html" }, + { "path": "../global-styles-engine" }, { "path": "../private-apis" }, { "path": "../hooks" }, { "path": "../html-entities" },