diff --git a/packages/block-editor/src/utils/dom.js b/packages/block-editor/src/utils/dom.js index 9c2e813ef742b6..0603e9bbb1db96 100644 --- a/packages/block-editor/src/utils/dom.js +++ b/packages/block-editor/src/utils/dom.js @@ -118,6 +118,22 @@ function isElementVisible( element ) { return true; } +/** + * Checks if the element is scrollable. + * + * @param {Element} element Element. + * @return {boolean} True if the element is scrollable. + */ +function isScrollable( element ) { + const style = window.getComputedStyle( element ); + return ( + style.overflowX === 'auto' || + style.overflowX === 'scroll' || + style.overflowY === 'auto' || + style.overflowY === 'scroll' + ); +} + /** * Returns the rect of the element including all visible nested elements. * @@ -136,19 +152,23 @@ function isElementVisible( element ) { */ export function getVisibleElementBounds( element ) { const viewport = element.ownerDocument.defaultView; + if ( ! viewport ) { return new window.DOMRectReadOnly(); } let bounds = element.getBoundingClientRect(); - const stack = [ element ]; let currentElement; while ( ( currentElement = stack.pop() ) ) { for ( const child of currentElement.children ) { if ( isElementVisible( child ) ) { - const childBounds = child.getBoundingClientRect(); + let childBounds = child.getBoundingClientRect(); + // If the parent is scrollable, use parent's scrollable bounds. + if ( isScrollable( currentElement ) ) { + childBounds = currentElement.getBoundingClientRect(); + } bounds = rectUnion( bounds, childBounds ); stack.push( child ); }