You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This method returns multiple Rect instances for a DOM Range.
Those instances are passed to ContextualBalloon#updatePosition()
Down the rabbit hole, BalloonPanelView#attachTo() is called, which has a fallback that moves the positioned element out of the viewport if it is invisible (e.g. cropped by parents).
Long story short, at some point, Rect#isVisible() is used. If the rect has no source that would pinpoint it on the Z-axis (ancestors-axis) in DOM, it always is visible because it's just an abstract rectangle in the space.
If Rects produced by Rect#getDomRangeRects() have DOMRect as a source, there's no way to determine whether they may be cropped. But if we set DOMRange as source, the logic will extract the common range ancestor and figure out whether the cropping occurs in Range#getVisible().
📝 Provide detailed reproduction steps (if any)
overflow: scroll✔️ Expected result
The balloon toolbar hides as soon as its anchor goes off the visible editing root.
❌ Actual result
It floats beyond the boundaries of the editing root
Screen.Recording.2026-01-29.at.13.31.12.mov
❓ Possible solution
Here's why it happens:
Rect#getDomRangeRects()ckeditor5/packages/ckeditor5-ui/src/toolbar/balloon/balloontoolbar.ts
Lines 316 to 350 in 9b29659
Rectinstances for a DOM Range.ContextualBalloon#updatePosition()BalloonPanelView#attachTo()is called, which has a fallback that moves the positioned element out of the viewport if it is invisible (e.g. cropped by parents).ckeditor5/packages/ckeditor5-ui/src/panel/balloon/balloonpanelview.ts
Line 296 in 9b29659
getOptimalPosition()ckeditor5/packages/ckeditor5-utils/src/dom/position.ts
Lines 146 to 148 in 9b29659
Rect#isVisible()is used. If the rect has no source that would pinpoint it on the Z-axis (ancestors-axis) in DOM, it always is visible because it's just an abstract rectangle in the space.Rectsproduced byRect#getDomRangeRects()haveDOMRectas a source, there's no way to determine whether they may be cropped. But if we setDOMRangeas source, the logic will extract the common range ancestor and figure out whether the cropping occurs inRange#getVisible().Extra
Addressing this issue will also fix #19710
If you'd like to see this fixed sooner, add a 👍 reaction to this post.