Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions backport-changelog/7.0/10470.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
https://github.com/WordPress/wordpress-develop/pull/10470

* https://github.com/WordPress/gutenberg/pull/71905
4 changes: 3 additions & 1 deletion docs/how-to-guides/themes/global-settings-and-styles.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ The settings section has the following structure:
"dimensions": {
"aspectRatio": false,
"minHeight": false,
"width": false,
},
"layout": {
"contentSize": "800px",
Expand Down Expand Up @@ -301,7 +302,7 @@ There's one special setting property, `appearanceTools`, which is a boolean and
- background: backgroundImage, backgroundSize
- border: color, radius, style, width
- color: link
- dimensions: aspectRatio, minHeight
- dimensions: aspectRatio, minHeight, width
- position: sticky
- spacing: blockGap, margin, padding
- typography: lineHeight
Expand Down Expand Up @@ -772,6 +773,7 @@ Each block declares which style properties it exposes via the [block supports me
"dimensions": {
"aspectRatio": "value",
"minHeight": "value"
"width": "value"
},
"filter": {
"duotone": "value"
Expand Down
2 changes: 1 addition & 1 deletion docs/how-to-guides/themes/theme-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ Use this setting to enable the following Global Styles settings:
- color: link
- spacing: blockGap, margin, padding
- typography: lineHeight
- dimensions: aspectRatio, minHeight
- dimensions: aspectRatio, minHeight, width
- position: sticky

```php
Expand Down
7 changes: 5 additions & 2 deletions docs/reference-guides/block-api/block-supports.md
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,7 @@ _**Note:** Since WordPress 6.2._
- Default value: null
- Subproperties:
- `minHeight`: type `boolean`, default value `false`
- `width`: type `boolean`, default value `false`

This value signals that a block supports some of the CSS style properties related to dimensions. When it does, the block editor will show UI controls for the user to set their values if [the theme declares support](/docs/how-to-guides/themes/global-settings-and-styles.md#opt-in-into-ui-controls).

Expand All @@ -638,20 +639,22 @@ supports: {
dimensions: {
aspectRatio: true // Enable aspect ratio control.
minHeight: true // Enable min height control.
width: true // Enable width control.
}
}
```

When a block declares support for a specific dimensions property, its attributes definition is extended to include the `style` attribute.

- `style`: an attribute of `object` type with no default assigned. This is added when `aspectRatio` or `minHeight` support is declared. It stores the custom values set by the user. For example:
- `style`: an attribute of `object` type with no default assigned. This is added when `aspectRatio`, `minHeight`, or `width` support is declared. It stores the custom values set by the user. For example:

```js
attributes: {
style: {
dimensions: {
aspectRatio: "16/9",
minHeight: "50vh"
minHeight: "50vh",
width: "400px",
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ New styles options are integrated into theme.json on a regular basis. Knowing th
| `spacing.margin.bottom` | 5.8 | 5.9 |
| `spacing.blockGap` | 5.9 | 5.9 |
| `dimensions.minHeight` | 6.2 | N/A |
| `dimensions.width` | 7.0 | N/A |
| `outline.color` | 6.2 | N/A |
| `outline.offset` | 6.2 | N/A |
| `outline.style` | 6.2 | N/A |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> This is the living specification for **version 3** of `theme.json`. This version works with WordPress 6.6 or later, and the latest Gutenberg plugin.
>
> There are some related documents that you may be interested in:
> There are some related documents that you may be interested in:
> - the [theme.json v1](/docs/reference-guides/theme-json-reference/theme-json-v1.md) specification,
> - the [theme.json v2](/docs/reference-guides/theme-json-reference/theme-json-v2.md) specification, and
> - the [reference to migrate from older theme.json versions](/docs/reference-guides/theme-json-reference/theme-json-migrations.md).
Expand All @@ -15,7 +15,7 @@ This documentation was generated from the JSON schema for theme.json.

The latest schema for version 3, including all the latest changes from the Gutenberg plugin, is available at <code>https://schemas.wp.org/trunk/theme.json</code>.

Theme.json schemas for each WordPress version are available at <code>https://schemas.wp.org/wp/{{version}}/theme.json</code>.
Theme.json schemas for each WordPress version are available at <code>https://schemas.wp.org/wp/{{version}}/theme.json</code>.
For example, a schema for WordPress 5.8 is available at <code>https://schemas.wp.org/wp/5.8/theme.json</code>.

See [Developing with theme.json](/docs/how-to-guides/themes/global-settings-and-styles.md#developing-with-themejson) for how to use the JSON schema in your editor.
Expand Down Expand Up @@ -46,7 +46,7 @@ Setting that enables the following UI tools:
- background: backgroundImage, backgroundSize
- border: color, radius, style, width
- color: link, heading, button, caption
- dimensions: aspectRatio, minHeight
- dimensions: aspectRatio, minHeight, width
- position: sticky
- spacing: blockGap, margin, padding
- typography: lineHeight
Expand Down Expand Up @@ -112,6 +112,7 @@ Settings related to dimensions.
| defaultAspectRatios | Allow users to choose aspect ratios from the default set of aspect ratios. | `boolean` | `true` |
| aspectRatios | Allow users to define aspect ratios for some blocks. | `[ { name, slug, ratio } ]` | |
| minHeight | Allow users to set custom minimum height. | `boolean` | `false` |
| width | Allow users to set custom width. | `boolean` | `false` |

---

Expand Down Expand Up @@ -268,6 +269,7 @@ Dimensions styles.
| -------- | ----------- | ---- |
| aspectRatio | Sets the `aspect-ratio` CSS property. | `string`, `{ ref }` |
| minHeight | Sets the `min-height` CSS property. | `string`, `{ ref }` |
| width | Sets the `width` CSS property. | `string`, `{ ref }` |

---

Expand Down
31 changes: 18 additions & 13 deletions lib/block-supports/dimensions.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,28 +43,33 @@ function gutenberg_register_dimensions_support( $block_type ) {
*
* @return array Block dimensions CSS classes and inline styles.
*/
function gutenberg_apply_dimensions_support( $block_type, $block_attributes ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
if ( wp_should_skip_block_supports_serialization( $block_type, 'dimensions' ) ) {
return array();
}

function gutenberg_apply_dimensions_support( $block_type, $block_attributes ) {
$attributes = array();

// Width support to be added in near future.
if ( wp_should_skip_block_supports_serialization( $block_type, 'dimensions' ) ) {
return $attributes;
}

$has_min_height_support = block_has_support( $block_type, array( 'dimensions', 'minHeight' ), false );
$block_styles = isset( $block_attributes['style'] ) ? $block_attributes['style'] : null;
$block_styles = $block_attributes['style'] ?? null;

if ( ! $block_styles ) {
return $attributes;
}

$skip_min_height = wp_should_skip_block_supports_serialization( $block_type, 'dimensions', 'minHeight' );
$dimensions_block_styles = array();
$dimensions_block_styles['minHeight'] = null;
if ( $has_min_height_support && ! $skip_min_height ) {
$dimensions_block_styles['minHeight'] = $block_styles['dimensions']['minHeight'] ?? null;
$dimensions_block_styles = array();
$supported_features = array( 'minHeight', 'width' );

foreach ( $supported_features as $feature ) {
$has_support = block_has_support( $block_type, array( 'dimensions', $feature ), false );
$skip_serialization = wp_should_skip_block_supports_serialization( $block_type, 'dimensions', $feature );

$dimensions_block_styles[ $feature ] = null;

if ( $has_support && ! $skip_serialization ) {
$dimensions_block_styles[ $feature ] = $block_styles['dimensions'][ $feature ] ?? null;
}
}

$styles = gutenberg_style_engine_get_styles( array( 'dimensions' => $dimensions_block_styles ) );

if ( ! empty( $styles['css'] ) ) {
Expand Down
8 changes: 8 additions & 0 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ class WP_Theme_JSON_Gutenberg {
* @since 6.2.0 Added `outline-*`, and `min-height` properties.
* @since 6.3.0 Added `writing-mode` property.
* @since 6.6.0 Added `background-[image|position|repeat|size]` properties.
* @since 7.0.0 Added `dimensions.width`.
*
* @var array
*/
Expand Down Expand Up @@ -297,6 +298,7 @@ class WP_Theme_JSON_Gutenberg {
'text-transform' => array( 'typography', 'textTransform' ),
'filter' => array( 'filter', 'duotone' ),
'box-shadow' => array( 'shadow' ),
'width' => array( 'dimensions', 'width' ),
'writing-mode' => array( 'typography', 'writingMode' ),
);

Expand Down Expand Up @@ -386,6 +388,7 @@ class WP_Theme_JSON_Gutenberg {
* @since 6.4.0 Added `layout.allowEditing`.
* @since 6.4.0 Added `lightbox`.
* @since 7.0.0 Added type markers to the schema for boolean values.
* @since 7.0.0 Added `dimensions.width`.
* @var array
*/
const VALID_SETTINGS = array(
Expand Down Expand Up @@ -425,6 +428,7 @@ class WP_Theme_JSON_Gutenberg {
'aspectRatios' => null,
'defaultAspectRatios' => null,
'minHeight' => null,
'width' => null,
),
'layout' => array(
'contentSize' => null,
Expand Down Expand Up @@ -539,6 +543,7 @@ class WP_Theme_JSON_Gutenberg {
'dimensions' => array(
'aspectRatio' => null,
'minHeight' => null,
'width' => null,
),
'filter' => array(
'duotone' => null,
Expand Down Expand Up @@ -641,6 +646,7 @@ class WP_Theme_JSON_Gutenberg {
const BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS = array(
'__experimentalBorder' => 'border',
'color' => 'color',
'dimensions' => 'dimensions',
'spacing' => 'spacing',
'typography' => 'typography',
);
Expand Down Expand Up @@ -741,6 +747,7 @@ public static function get_element_class_name( $element ) {
*
* @since 6.0.0
* @since 6.2.0 Added `dimensions.minHeight` and `position.sticky`.
* @since 7.0.0 Added `dimensions.width`.
* @var array
*/
const APPEARANCE_TOOLS_OPT_INS = array(
Expand All @@ -756,6 +763,7 @@ public static function get_element_class_name( $element ) {
array( 'color', 'caption' ),
array( 'dimensions', 'aspectRatio' ),
array( 'dimensions', 'minHeight' ),
array( 'dimensions', 'width' ),
// BEGIN EXPERIMENTAL.
// Allow `position.fixed` to be opted-in by default.
// Sticky position support was backported to WordPress 6.2 in https://core.trac.wordpress.org/ticket/57618.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export function useHasDimensionsPanel( settings ) {
const hasMargin = useHasMargin( settings );
const hasGap = useHasGap( settings );
const hasMinHeight = useHasMinHeight( settings );
const hasWidth = useHasWidth( settings );
const hasAspectRatio = useHasAspectRatio( settings );
const hasChildLayout = useHasChildLayout( settings );

Expand All @@ -50,6 +51,7 @@ export function useHasDimensionsPanel( settings ) {
hasMargin ||
hasGap ||
hasMinHeight ||
hasWidth ||
hasAspectRatio ||
hasChildLayout )
);
Expand Down Expand Up @@ -79,6 +81,10 @@ function useHasMinHeight( settings ) {
return settings?.dimensions?.minHeight;
}

function useHasWidth( settings ) {
return settings?.dimensions?.width;
}

function useHasAspectRatio( settings ) {
return settings?.dimensions?.aspectRatio;
}
Expand Down Expand Up @@ -206,6 +212,7 @@ const DEFAULT_CONTROLS = {
margin: true,
blockGap: true,
minHeight: true,
width: true,
aspectRatio: true,
childLayout: true,
};
Expand Down Expand Up @@ -384,6 +391,17 @@ export default function DimensionsPanel( {
};
const hasMinHeightValue = () => !! value?.dimensions?.minHeight;

// Width
const showWidthControl = useHasWidth( settings );
const widthValue = decodeValue( inheritedValue?.dimensions?.width );
const setWidthValue = ( newValue ) => {
onChange( setImmutably( value, [ 'dimensions', 'width' ], newValue ) );
};
const resetWidthValue = () => {
setWidthValue( undefined );
};
const hasWidthValue = () => !! value?.dimensions?.width;

// Aspect Ratio
const showAspectRatioControl = useHasAspectRatio( settings );
const aspectRatioValue = decodeValue(
Expand Down Expand Up @@ -439,6 +457,7 @@ export default function DimensionsPanel( {
...previousValue?.dimensions,
minHeight: undefined,
aspectRatio: undefined,
width: undefined,
},
};
}, [] );
Expand Down Expand Up @@ -688,6 +707,23 @@ export default function DimensionsPanel( {
/>
</ToolsPanelItem>
) }
{ showWidthControl && (
<ToolsPanelItem
hasValue={ hasWidthValue }
label={ __( 'Width' ) }
onDeselect={ resetWidthValue }
isShownByDefault={
defaultControls.width ?? DEFAULT_CONTROLS.width
}
panelId={ panelId }
>
<HeightControl
Copy link
Contributor

Choose a reason for hiding this comment

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

The naming here is a little unfortunate, using a HeightControl for a width control seems odd.

Copy link
Member

@ramonjd ramonjd Nov 14, 2025

Choose a reason for hiding this comment

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

Yes, we should change this. If width and height are going to share a control, then WidthHeightControl?

Copy link
Contributor

Choose a reason for hiding this comment

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

We had a similar discussion in the past when we implemented the font size preset UI. At that time, we discussed exposing a generic SizeControl component, but ultimately created it as an internal component that was part of the font size preset UI. See: #62328 (comment) for more details.

In a follow-up, we might be able to reconsider creating a more abstract component for sizing.

label={ __( 'Width' ) }
value={ widthValue }
onChange={ setWidthValue }
/>
</ToolsPanelItem>
) }
{ showAspectRatioControl && (
<AspectRatioTool
hasValue={ hasAspectRatioValue }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ export function useSettingsForBlockElement(
}
} );

[ 'aspectRatio', 'minHeight' ].forEach( ( key ) => {
[ 'aspectRatio', 'minHeight', 'width' ].forEach( ( key ) => {
if ( ! supportedStyles.includes( key ) ) {
updatedSettings.dimensions = {
...updatedSettings.dimensions,
Expand Down
11 changes: 8 additions & 3 deletions packages/block-editor/src/hooks/dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export function DimensionsPanel( { clientId, name, setAttributes, settings } ) {
},
[ clientId, isEnabled ]
);

const [ visualizedProperty, setVisualizedProperty ] = useVisualizer();
const onChange = ( newStyle ) => {
setAttributes( {
Expand Down Expand Up @@ -156,17 +157,21 @@ export function hasDimensionsSupport( blockName, feature = 'any' ) {
}

if ( feature === 'any' ) {
return !! ( support?.aspectRatio || !! support?.minHeight );
return !! (
support?.aspectRatio ||
!! support?.minHeight ||
!! support?.width
);
}

return !! support?.[ feature ];
}

export default {
useBlockProps,
attributeKeys: [ 'minHeight', 'style' ],
attributeKeys: [ 'minHeight', 'width', 'style' ],
hasSupport( name ) {
return hasDimensionsSupport( name, 'aspectRatio' );
return hasDimensionsSupport( name );
},
};

Expand Down
4 changes: 4 additions & 0 deletions packages/block-editor/src/hooks/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ export function useBlockSettings( name, parentLayout ) {
units,
aspectRatio,
minHeight,
width,
layout,
borderColor,
borderRadius,
Expand Down Expand Up @@ -321,6 +322,7 @@ export function useBlockSettings( name, parentLayout ) {
'spacing.units',
'dimensions.aspectRatio',
'dimensions.minHeight',
'dimensions.width',
'layout',
'border.color',
'border.radius',
Expand Down Expand Up @@ -430,6 +432,7 @@ export function useBlockSettings( name, parentLayout ) {
dimensions: {
aspectRatio,
minHeight,
width,
},
layout,
parentLayout,
Expand Down Expand Up @@ -466,6 +469,7 @@ export function useBlockSettings( name, parentLayout ) {
units,
aspectRatio,
minHeight,
width,
layout,
parentLayout,
borderColor,
Expand Down
Loading
Loading