diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js
index fb11b3f50a5b6..b7c25595dcfcc 100644
--- a/packages/block-library/src/image/edit.js
+++ b/packages/block-library/src/image/edit.js
@@ -23,6 +23,7 @@ import { useEffect, useRef, useState } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { image as icon, plugins as pluginsIcon } from '@wordpress/icons';
import { store as noticesStore } from '@wordpress/notices';
+import { useResizeObserver } from '@wordpress/compose';
/**
* Internal dependencies
@@ -109,6 +110,9 @@ export function ImageEdit( {
} = attributes;
const [ temporaryURL, setTemporaryURL ] = useState( attributes.blob );
+ const [ contentResizeListener, { width: containerWidth } ] =
+ useResizeObserver();
+
const altRef = useRef();
useEffect( () => {
altRef.current = alt;
@@ -364,35 +368,43 @@ export function ImageEdit( {
};
return (
-
+ <>
+
+ {
+ // The listener cannot be placed as the first element as it will break the in-between inserter.
+ // See https://github.com/WordPress/gutenberg/blob/71134165868298fc15e22896d0c28b41b3755ff7/packages/block-editor/src/components/block-list/use-in-between-inserter.js#L120
+ contentResizeListener
+ }
+ >
);
}
diff --git a/packages/block-library/src/image/image.js b/packages/block-library/src/image/image.js
index 646299bb7e089..3ad12d8dca4b6 100644
--- a/packages/block-library/src/image/image.js
+++ b/packages/block-library/src/image/image.js
@@ -109,6 +109,7 @@ export default function Image( {
clientId,
blockEditingMode,
parentLayoutType,
+ containerWidth,
} ) {
const {
url = '',
@@ -928,6 +929,7 @@ export default function Image( {
// @todo It would be good to revisit this once a content-width variable
// becomes available.
const maxWidthBuffer = maxWidth * 2.5;
+ const maxContentWidth = containerWidth || maxWidthBuffer;
let showRightHandle = false;
let showLeftHandle = false;
@@ -973,9 +975,9 @@ export default function Image( {
} }
showHandle={ isSingleSelected }
minWidth={ minWidth }
- maxWidth={ maxWidthBuffer }
+ maxWidth={ maxContentWidth }
minHeight={ minHeight }
- maxHeight={ maxWidthBuffer / ratio }
+ maxHeight={ maxContentWidth / ratio }
lockAspectRatio={ ratio }
enable={ {
top: false,
@@ -986,6 +988,21 @@ export default function Image( {
onResizeStart={ onResizeStart }
onResizeStop={ ( event, direction, elt ) => {
onResizeStop();
+
+ // Clear hardcoded width if the resized width is close to the max-content width.
+ if (
+ // Only do this if the image is bigger than the container to prevent it from being squished.
+ // TODO: Remove this check if the image support setting 100% width.
+ naturalWidth >= maxContentWidth &&
+ Math.abs( elt.offsetWidth - maxContentWidth ) < 10
+ ) {
+ setAttributes( {
+ width: undefined,
+ height: undefined,
+ } );
+ return;
+ }
+
// Since the aspect ratio is locked when resizing, we can
// use the width of the resized element to calculate the
// height in CSS to prevent stretching when the max-width