position:sticky - Nested `position: sticky` offsets for scroll position more than once
Reported by
star.c...@gmail.com,
Dec 9 2016
|
||||||||||||||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.21 Safari/537.36 Steps to reproduce the problem: 1. Open https://jsbin.com/holoriyije/1/edit?html,output 2. Run with JS 3. Scroll down the table. What is the expected behavior? The header of the table does not move. What went wrong? The header of the table moves down. Did this work before? N/A Does this work in other browsers? N/A Chrome version: 56.0.2924.21 Channel: beta OS Version: 6.1 (Windows 7, Windows Server 2008 R2) Flash Version: Shockwave Flash 24.0 r0
,
Dec 11 2016
,
Dec 12 2016
Tested in chrome Canary #56.0.2949.0 , Beta #56.0.2924.21 & dev #56.0.2924.18 on Win 10.0 , Mac 10.11.6 & Ubuntu 14.04 able to reproduce the issue. Below are the Bisect Details: Bisect Info: ============= Good Build: 56.0.2909.0(Revision - 429737) Bad Build: 56.0.2910.0 (Revision - 430103) Bisect URL: =========== You are probably looking for a change made after 429926 (known good), but no later than 429927 (first known bad). CHANGELOG URL: =============== https://chromium.googlesource.com/chromium/src/+log/851c6f72587756eab07e345c2212c0d45c8c10e1..77a8c51a440e0741315ff5e9e77441b86cbbc56d From the CL above, assigning the issue to the concern owner @ flackr: ------------------ Could you please look into the issue, pardon me if it has nothing to do with your changes and if possible please assign it to concern owner. Review-Url: https://codereview.chromium.org/2468283005
,
Dec 12 2016
,
Dec 12 2016
I can reproduce on 57.0.2950.0 (Linux), will take a look since flackr@ is OOO. Note that I'm much less familiar with the position:sticky spec :). Other browsers behaviors are interesting. * Firefox 50.0.2 (Linux) doesn't seem to respect the position:sticky at all here - the entire table scrolls. There is also a strange rendering glitch in FF where the header borders are not drawn. See attached images. * Safari 10.0.1 (OSX) has the same behavior as Chrome interestingly (using -webkit-sticky of course). The header moves downwards as you scroll.
,
Dec 13 2016
,
Jan 9 2017
Yes, so the issue is that we are double-counting the offset. PaintLayer::updateLayerPosition adds the result of LayoutBoxModelObject::offsetForInFlowPosition, which then uses the sticky constraints, which have a vertical offset for both the header row and cell. So the cell is offset an additional N units vertically. I'm not familiar enough with the code to immediately know which of the following is wrong for the table cell. Changing any of them to not offset the table cell would fix this bug: 1. The sticky constraints calculation, 2. LayoutBoxModelObject::stickyPositionOffset, 3. LayoutBoxModelObject::offsetForInFlowPosition, or 4. PaintLayer::updateLayerPosition Will check with flackr@ when he is in the office.
,
Jan 9 2017
Interestingly, my attempts to make a <div> based repro have so far failed: https://output.jsbin.com/qizuqer/1 The difference appears to be in m_scrollContainerRelativeContainingBlockRect. In the <div> case, the child has m_scrollContainerRelativeContainingBlockRect.maxY() == m_scrollContainerRelativeStickyBoxRect.maxY(), whilst the parent has m_scrollContainerRelativeContainingBlockRect.maxY() >>> m_scrollContainerRelativeStickyBoxRect.maxY(). In the <table> case, both child and parent have the same m_scrollContainerRelativeContainingBlockRect.maxY() >>> m_scrollContainerRelativeStickyBoxRect.maxY(). This may just be my failure to make a proper repro. Digging further to see.
,
Jan 9 2017
Reason for #8 is that the containing block for the child <div> is the outer div, whereas the containing block for *both* parent and child in the <table> case is the overall table block.
,
Jan 10 2017
Chatting with flackr@, we found that the behavior of 'position' for table elements is somewhat interesting already. In the current spec for position: "The effect of ‘position: sticky’ on table elements is the same as for ‘position: relative’." "The effect of position:relative on table-*-group, table-row, table-column, table-cell, and table-caption elements is undefined."[1] The draft spec however updates position:relative to read: "The effect of position: relative on table elements is defined as follows: * table-row-group, table-header-group, table-footer-group and table-row offset relative to its normal position within the table. If table-cells span multiple rows, only the cells originating in the relative positioned row are offset. * table-column-group, table-column do not offset the respective column and has no visual affect when position: relative is applied. * table-caption and table-cell offset relative to its normal position within the table. If a table cell spans multiple columns or rows the full spanned cell is offset." I'm still trying to understand what the 'normal position' within the table is for a table-cell versus table-row. [1] Currently, Chrome and Firefox treat position: relative differently for tables. Chrome ignores position: relative for table rows, but allows it for cells. Firefox allows it for both. Both agents are correct, since the published spec leaves it as undefined.
,
Jan 11 2017
Seems like this is actually a problem with regular nested sticky elements if the outer one (which contains the inner one) is large enough for the inner one to move, see https://output.jsbin.com/moqube. The problem is that we've statically computed the sticky position constraints (stickyBoxRect and containingBlockRect) but their positions are not actually static at layout because ancestors may also be sticky (and later shifted). +chrishtr, It seems that to properly account for this we either need to remove the optimization of saving sticky constraints or we need to know the additional accumulated sticky offsets of the sticky elements between the sticky box and its container, and the container and the scroll ancestor (which perhaps means keeping a hierarchical chain of sticky elements).
,
Jan 11 2017
Here's a nested example where the inner element should only move about 2/3 of the way down the outer one before the outer one starts moving too. Since we don't know that the outer one is moving the constraints for the inner one, we continue to offset the inner one. https://output.jsbin.com/moxoxa
,
Jan 11 2017
Here's a thought for what we could do to handle this. If as part of the sticky constraints we save the nearest sticky ancestor between the sticky box and container, and between the container and scroll ancestor, we could ask for their sticky offset and offset the sticky constraint rects by this amount before computing our sticky offset (and if there are multiple sticky elements between then they would subsequently ask their next nearest sticky ancestor).
,
Jan 18 2017
FYI; work on this is underway. It is proving to be tricky to get the accumulation logic correct, so taking a little longer than we'd like :).
,
Jan 26 2017
,
Feb 2 2017
Gentle ping..!Could you please update if any progress on it.
,
Feb 2 2017
Code review ongoing at https://codereview.chromium.org/2636253002/ At the current time, we believe we've fixed most of the problems on the main-thread side[0], but the compositor implementation is still going. My hope is to wrap this up within the next week, but BlinkOn is throwing a wrench into the review process atm :). [0]: The exception is sticky elements within fixed elements, see issue 686164.
,
Feb 8 2017
A friendly reminder that M57 Stable is launch is coming soon! Your bug is labelled as Stable ReleaseBlock, pls make sure to land the fix and get it merged into the release branch ASAP so it gets enough baking time in Beta (before Stable promotion). Thank you!
,
Feb 14 2017
smcgruer@ can we have an update on the fix please. If the Cl is well backed in Canary and dev please request for merge to M57(branch: 2987).
,
Feb 14 2017
Punting to M58. The CL is too far from even being submitted for 57, and the use-case isn't common enough to keep this targeted at 57.
,
Feb 22 2017
Friendly Ping!! Still we are able to reproduce the issue on latest Canary-58.0.3019.0. smcgruer@, Could you please look into this & update the thread. Thank you.
,
Feb 24 2017
Work is continuing on this issue. The original CL grew out of control and is being split into parts - some which fix non-nested bugs, and then two larger CLs for the main-thread and compositor side of the nested sticky issue (this bug). The main thread CL is https://codereview.chromium.org/2708883005/ and is (hopefully!) nearing completion.
,
Feb 24 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/b693f94a81551da0334f9fb297813e617d9539c0 commit b693f94a81551da0334f9fb297813e617d9539c0 Author: smcgruer <smcgruer@chromium.org> Date: Fri Feb 24 22:07:18 2017 Handle nested position:sticky elements correctly (main thread) In order to correctly calculate the sticky offset for nested sticky, we must track the accumulated sticky offset from our ancestor sticky elements. This accumulation must then be used to adjust the location of the two constraint rects. This patch fixed nested position: sticky only for the main thread side. A compositor fix will follow in a later patch. To ensure that nested sticky behaves properly in the meantime, we also disallow compositing of sticky elements if nesting is detected. BUG= 672710 CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2 Review-Url: https://codereview.chromium.org/2708883005 Cr-Commit-Position: refs/heads/master@{#452944} [add] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/LayoutTests/fast/css/sticky/nested/sticky-nested-deep-expected.html [add] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/LayoutTests/fast/css/sticky/nested/sticky-nested-deep.html [add] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/LayoutTests/fast/css/sticky/nested/sticky-nested-inline-expected.html [add] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/LayoutTests/fast/css/sticky/nested/sticky-nested-inline.html [add] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/LayoutTests/fast/css/sticky/nested/sticky-nested-left-expected.html [add] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/LayoutTests/fast/css/sticky/nested/sticky-nested-left.html [add] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/LayoutTests/fast/css/sticky/nested/sticky-nested-table-expected.html [add] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/LayoutTests/fast/css/sticky/nested/sticky-nested-table.html [add] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/LayoutTests/fast/css/sticky/nested/sticky-nested-top-expected.html [add] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/LayoutTests/fast/css/sticky/nested/sticky-nested-top.html [modify] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/Source/core/frame/FrameView.cpp [modify] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp [modify] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/Source/core/layout/LayoutBoxModelObjectTest.cpp [modify] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/Source/core/layout/LayoutObject.cpp [modify] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/Source/core/layout/MapCoordinatesFlags.h [modify] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp [modify] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.cpp [modify] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinderTest.cpp [modify] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.cpp [modify] https://crrev.com/b693f94a81551da0334f9fb297813e617d9539c0/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.h
,
Feb 28 2017
Tested the issue on Windows-7, Mac 10.12.2 and Linux Ubuntu-14.04 using Chrome version 58.0.3025.5 as per the comment #0. Observed that the header of the table moves down.Seems the issue has not been fixed. Please find the attached screen cast. Thanks..
,
Feb 28 2017
That is very interesting, thank you for spotting that sureshkumari@ ! I had been using https://output.jsbin.com/tiqipi/35 as my table test, but that has a sticky <thead>, <tr>, and <th>. I had not spotted that the original reproduction only has a sticky <tr> and <th>, *not* a sticky <thead>. https://codereview.chromium.org/2711803002/ is an in-flight CL (waiting for OWNERS :() that will 'fix' this because we intend to temporarily restrict sticky from <thead> and <tr> and only allow it on <th>. However I will take a look into the underlying issue too because I thought it should work... possibly something was lost when we pared down the main-only CL.
,
Feb 28 2017
crbug.com/695179 is now fixed, so https://jsbin.com/holoriyije/1/edit?html,output will 'work' because Chrome will ignore the sticky on the <tr>, but it's not a proper fix. I will continue to investigate why this didn't work so that when we turn sticky back on for <tr> and <thead> things don't break.
,
Mar 1 2017
+1 sureshkumari@ for thorough verification. Thank you!
,
Mar 7 2017
Tested the issue on Latest Dev# 58.0.3029.6 on Mac and Linux and found the issue to be Fixed. The header does not move and fixed to the position. Hence adding TE-Verified Labels for Mac and Linux. Attaching Screencast (Mac and Linux) for reference. Note: This issue is still seen on Windows 10 for the above mentioned version# 58.0.3029.6. @smcgruer -- Could you please look into it and provide an update. Thanks in Advance.
,
Mar 7 2017
@msrchandra - this is likely a composited (not yet fixed) vs non-composited (fixed) issue. Was the Windows device a high-DPI screen? The compositor side fix is in review currently.
,
Mar 7 2017
@smcgruer -- Thank You for the update. Removing TE-Verified labels as of now. Will update once after the CL is landed on Windows. Yes, the issue tested on Windows 10 High DPI Screen. Thank You.
,
Mar 14 2017
Tested the issue on Latest Dev# 58.0.3029.19 on Windows10 high-DPI screen and observed that the header does not move and fixed to the position. Hence adding TE-Verified Labels. Attaching Screencast (Windows 10) for reference.
,
Mar 14 2017
The compositor-size fix has not landed yet. The behavior observed in #31 is incorrect; the table header row is meant to stay fixed and *not* scroll upwards as you scroll the table. (Possibly some confusion with what is referred to as the 'header' here - the large text in the initial jsbin example is not the header, the first row of the table is.) https://jsbin.com/holoriyije/1/edit?html,output currently only works on non-composited (e.g. low DPI) setup. Removing verified labels.
,
Mar 17 2017
Thanks for the updates. Since the issue is tagged as RB - Stable please try to resolve ASAP.
,
Mar 17 2017
The fix is complex enough that we shouldn't merge to 58; punting to RB 59. I'm expecting to land the final CL within the next few days, so that's a positive :).
,
Mar 18 2017
This may caused a regression, please check issue 702927 (works in stable version 57, but is broken now in Canary)
,
Mar 20 2017
,
Mar 24 2017
,
Mar 24 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/29014fffc71e122447fb29f32915ae421b8eded4 commit 29014fffc71e122447fb29f32915ae421b8eded4 Author: smcgruer <smcgruer@chromium.org> Date: Fri Mar 24 14:34:43 2017 Handle nested position:sticky elements correctly (compositor) In order to correctly calculate the sticky offset for nested sticky, we must track the accumulated sticky offset from our ancestor sticky elements. This accumulation must then be used to adjust the location of the two constraint rects. On the compositor side, the goal of the sticky calculation is to adjust the rectangle by any additional composited scroll offset on top of the main thread scroll position (as the sticky calculation will already have adjusted for that scroll). BUG= 672710 CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2 Review-Url: https://codereview.chromium.org/2733633002 Cr-Commit-Position: refs/heads/master@{#459419} [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/cc/blink/web_layer_impl.cc [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/cc/layers/layer.cc [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/cc/layers/layer_sticky_position_constraint.cc [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/cc/layers/layer_sticky_position_constraint.h [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/cc/trees/layer_tree_host_common_unittest.cc [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/cc/trees/property_tree.cc [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/cc/trees/property_tree.h [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/cc/trees/property_tree_builder.cc [add] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/LayoutTests/compositing/overflow/composited-nested-sticky-deep-expected.html [add] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/LayoutTests/compositing/overflow/composited-nested-sticky-deep.html [add] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/LayoutTests/compositing/overflow/composited-nested-sticky-left-expected.html [add] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/LayoutTests/compositing/overflow/composited-nested-sticky-left.html [add] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/LayoutTests/compositing/overflow/composited-nested-sticky-table-expected.html [add] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/LayoutTests/compositing/overflow/composited-nested-sticky-table.html [add] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/LayoutTests/compositing/overflow/composited-nested-sticky-top-expected.html [add] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/LayoutTests/compositing/overflow/composited-nested-sticky-top.html [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.cpp [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinderTest.cpp [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.h [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/public/platform/WebLayer.h [modify] https://crrev.com/29014fffc71e122447fb29f32915ae421b8eded4/third_party/WebKit/public/platform/WebLayerStickyPositionConstraint.h
,
Mar 24 2017
,
Mar 28 2017
Tested the issue on Windows-7,Mac-10.12.3 and Linux Ubuntu-14.04 using chrome version# 59.0.3053.3 with the steps mentioned in comment#0. Observed that the fix is working as expected. Hence adding TE-Verified labels. Please find the attached screen cast for the same. Thanks!! |
||||||||||||||||||||
►
Sign in to add a comment |
||||||||||||||||||||
Comment 1 by nyerramilli@chromium.org
, Dec 9 2016