scroll anchoring breaks crbug.com on mobile |
|||||
Issue descriptionWith scroll anchoring enabled, go to crbug.com/592037 . Slowly scroll down. Once you get to "back to list", the scroll jumps back up to the top. This page is doing something very weird to the DOM at this point. Without scroll anchoring enabled you see a flicker. But, even so, we should figure out what's going wrong since we'd be regressing this content.
,
Mar 28 2016
,
Mar 28 2016
The flicker is probably issue 581875 .
,
Mar 28 2016
Disregard #3, this is on mobile so it won't be related to that.
,
Mar 28 2016
,
Mar 31 2016
,
Mar 31 2016
,
Mar 31 2016
I investigated this bug. Monorail's left-hand sidebar is a DIV with id="meta-float" inside a TD. The scroll handler in tracker-display.js is trying to set position:fixed on #meta-float if - the TD is partially offscreen, and - #meta-float fits entirely within the visible part of the TD. This makes sense when TD actually behaves like a table cell. But the @media query in ph_mobile.css gives the TD display: block when the viewport is narrow. When the TD has display: block, - it's never taller than #meta-float plus its own border + padding, and - it shrinks to near 0 if #meta-float becomes position: fixed. The result of this is that there is a small window of scroll positions in which every scroll event toggles #meta-float between position: fixed and position: relative. The size of this window is equal to the border + padding on the TD. Setting position: fixed makes the whole comment list jump up by a distance equal to the height of #meta-float, since it is no longer in-flow. This causes the flickering effect when scroll anchoring is off. When scroll anchoring is on, things get even more interesting: During the layout from setting position: fixed, we anchor to the bottom left corner of the TD. Because the TD shrinks, we scroll up to compensate. ScrollAnchor avoids anchoring to position: fixed elements, but that doesn't matter here - the TD itself is not position: fixed, only its child is. Besides, this adjustment is theoretically correct - it preserves the viewport-relative location of the comment list (which now fills most of the viewport). Unfortunately, the very next scroll event restores position: relative, so the comment list is pushed down again. But this time we anchor to the header, so there is no corresponding scroll adjustment. From Monorail's perspective, a quick workaround is to remove border and padding on #issuemeta. For scroll anchoring, it's not clear to me if there is a good solution to the general problem of "scroll handler bounces between two layout states with different anchor nodes". One thing that might help here is to set the anchor node based on the hit test for the touch event. That maps well to the user's expectation that the thing under their finger stays under their finger. I have attached a minimization of this bug, with exaggerated padding.
,
Apr 4 2016
We need to dig into that reduction more to see what we can do. Interestingly, if the bug has just the right number of comments, this bug reproduces on stable without scroll anchoring. Scroll anchoring definitely makes it worse though (i.e. it happens regardless of the number of comments).
,
May 18 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/2fd28b5102e73c49b3891d9bc7c05ffda979e2ea commit 2fd28b5102e73c49b3891d9bc7c05ffda979e2ea Author: skobes <skobes@chromium.org> Date: Wed May 18 21:27:18 2016 Implement bounce suppression in ScrollAnchor. An element can "bounce", by making the inverse of its last movement, when a scroll anchoring adjustment interacts with a scroll event handler that changes layout at a scroll offset threshold. ScrollAnchor now detects bounces by tracking the most recent adjustment and the element that triggered it (even if we have anchored to a different element since then), and suppresses repeat bounces. BUG= 598233 , 601906 , 603376 Review-Url: https://codereview.chromium.org/1971423002 Cr-Commit-Position: refs/heads/master@{#394552} [add] https://crrev.com/2fd28b5102e73c49b3891d9bc7c05ffda979e2ea/third_party/WebKit/LayoutTests/fast/layout/scroll-anchoring/onscroll-bouncing.html [modify] https://crrev.com/2fd28b5102e73c49b3891d9bc7c05ffda979e2ea/third_party/WebKit/Source/core/layout/LayoutObject.cpp [modify] https://crrev.com/2fd28b5102e73c49b3891d9bc7c05ffda979e2ea/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp [modify] https://crrev.com/2fd28b5102e73c49b3891d9bc7c05ffda979e2ea/third_party/WebKit/Source/core/layout/ScrollAnchor.h
,
Jul 7 2016
This is fixed. The page still does its weird things due to the broken assumptions in tracker-display.js, but we no longer get "stuck" at the top. |
|||||
►
Sign in to add a comment |
|||||
Comment 1 by ojan@chromium.org
, Mar 28 2016