Fix position:sticky when inside fixed subtree
In https://crrev.com/4d25b125dae5 I changed the scroll tree parenting logic so that elements in position:fixed subtrees have the LayoutView's ScrollNode as the scroll parent. This made sense since scrolling over a fixed element should cause the document to scroll. However, this is slightly different from how the transform tree looks. Because scrolling the document doesn't cause position:fixed eement so translate, these nodes don't have the LayoutView's ScrollTranslation transform node as an ancestor. As a simple example, a scrolling document with a position:fixed <div> scroller will generate the following scroll and transform trees (approximately): *ScrollTree* *TransformTree* Root Root | | VisualViewport Translation VisualViewport | / \ LayoutView Translation / \ | Fixed LayoutView Fixed Scroller Translation The situation above makes sense for what parent-child relationships mean in each tree: the scroll tree encodes how scrolls chain; scrolling on a child should bubble up to its parent in this tree. The transform tree encodes the physical effect of scrolling a node. In the above example, scrolling from the fixed scroller should bubble up to the LayoutView (when the scroller is fully scrolled) but scrolling the LayoutView will not cause movement of the fixed scroller. The above makes sense but caused sticky code to get confused. A sticky constraint is attached to the scroll translation node. With the above situation, this meant that inside a fixed subtree, we'd attach it to the VisualViewport's scroll translation node. This was unexpected; the constraints are in "document coordinates", meaning that to translate them into the viewport space we must apply the scroll offset [1]. The compositor would use the visual viewport's (typically 0) scroll offset to adjust these values, leading to incorrect calculations. This previously worked because the scroll node used in a fixed subtree would be the visual viewport (before the CL mentioned at the top). In [2] we check whether the current overflow clip is also our scroller, prior to the CL this check have failed because "our scroller" was the visual viewport but our clip was the LayoutView. Now they are both the LayoutView. The fix in this CL is to make the check in [2] more stringent; we also want to make sure that our scroller is the nearest scroller in the transform tree. That is, if we scroll it, will we cause the current node to move? If not, we don't need a sticky constraint on the compositor because user scrolling can't change the sticky's offset relative to its clip. [1] https://cs.chromium.org/chromium/src/cc/trees/property_tree.cc?l=321&rcl=628f869d1fda631a85f051ad13b5d278319298fc [2] https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc?l=553&rcl=99a5a1266f303ba6ae46174a2b4cbd165ea7e934 Bug: 1019142 Change-Id: I781943ff43514905d399803c780c6081d7d47e8f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2097542Reviewed-by:Robert Flack <flackr@chromium.org> Commit-Queue: David Bokan <bokan@chromium.org> Cr-Commit-Position: refs/heads/master@{#750264}
Showing
Please register or sign in to comment