{inc} div gets inconsistent position in incremental vs. full layout with dynamic change to 'padding` on sticky-positioned element whose position wants to put it outside the scrollport
Categories
(Core :: Layout: Positioned, defect)
Tracking
()
People
(Reporter: tsmith, Assigned: TYLin)
References
(Blocks 3 open bugs, Regressed 2 open bugs)
Details
(Keywords: testcase)
Attachments
(8 files, 2 obsolete files)
|
7.61 KB,
application/x-zip-compressed
|
Details | |
|
1.71 KB,
text/html
|
Details | |
|
1.79 KB,
text/html
|
Details | |
|
701 bytes,
text/html
|
Details | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review |
Found while fuzzing m-c 20220105-138105a14659 (--enable-debug --enable-fuzzing)
To reproduce via Grizzly Replay:
$ pip install fuzzfetch grizzly-framework
$ python -m fuzzfetch -d --fuzzing -n firefox
$ python -m grizzly.replay ./firefox/firefox testcase.zip
LQC Signature: tag-div,x-extreme,left-extreme,right-extreme
LQC Results:
Conflicting dimensions for element two<div>
Dimensions after reload: {"x":1371.683349609375,"left":1371.683349609375,"right":1424.683349609375}
Dimensions after modify: {"x":4855.10009765625,"left":4855.10009765625,"right":4908.10009765625}
END of LQC Results
CSS Styles Used: {
"base_styles": [
"background-color",
"border-right-style",
"inset-inline-start",
"min-height",
"min-width",
"overflow-x",
"position",
"transform",
"width"
],
"modified_styles": [
"padding-block-start"
]
}
If a Pernosco session would be helpful please ni? :tsmith.
| Reporter | ||
Comment 1•3 years ago
|
||
Comment 2•3 years ago
|
||
Bugmon Analysis
Unable to reproduce bug 1748891 using build mozilla-central 20220105170324-138105a14659. Without a baseline, bugmon is unable to analyze this bug.
Removing bugmon keyword as no further action possible. Please review the bug and re-add the keyword for further analysis.
Comment 3•3 years ago
|
||
I can reproduce. STR are
(1) Load testcase.html
(2) F12 to open console
(3) inspect the logged output
I see:
Dimensions after style changes, before reload
#two
Object { x: 4855.10009765625, left: 4855.10009765625, right: 4908.10009765625 }
Dimensions after reload
#two
Object { x: 1371.683349609375, left: 1371.683349609375, right: 1424.683349609375 }
(All three values are substantially larger in the "after style changes" part)
Updated•3 years ago
|
Comment 4•3 years ago
|
||
Here's a further-reduced testcase, which I've also edited to be less-fully-automated, so you can see the rendering after the initial load + dynamic-style-change, and see how it changes when the DOM is reserialized.
In Chrome, when you load this testcase, the yellow-and-teal element is visible (and there's no rendering difference and no difference in the console.log output when you click the button)
In Firefox, when you first load this testcase, the scrollable area is fully pink. When you click the button, the yellow-and-teal element appears. (Also: scrolling is a bit horked -- if you load the testcase and try to scroll right by e.g. clicking the pink area and then pressing rightarrow on your keyboard, the scrollbar moves very slowly & jittery; it looks like we're continuously pushing the yellow and teal element out-of-view which is forever creating more scrollable distance.)
Updated•3 years ago
|
Comment 5•3 years ago
|
||
Here's a further-reduced testcase.
Side note, this is kinda related to the discussion on https://bugs.chromium.org/p/chromium/issues/detail?id=1327794
There's still a bit I don't understand about Chrome's behavior there, but one thing that came out of the discussion is that Chrome is computing scrollable overflow by assuming the sticky-positioned element is at its static position.
If we did that, I think that would fix this issue.
Comment 6•3 years ago
|
||
| Assignee | ||
Comment 7•1 year ago
|
||
This helper is used in nsContainerFrame::ConsiderChildOverflow() and
nsLayoutUtils::UnionChildOverflow().
This patch is adapted from a WIP written by
Daniel Holbert <dholbert@cs.stanford.edu>
in https://phabricator.services.mozilla.com/D150427
Updated•1 year ago
|
| Assignee | ||
Comment 8•1 year ago
|
||
In an incremental reflow for scroll container (e.g. resizing scroll container),
toggling the visibility of vertical and horizontal scrollbars in TryLayout() can
affect the position of sticky elements. We'd want to reflow the scrolled frame
and update the sticky positions.
The WPTs are inspired from the reduced testcase in bug 1835705 comment 8. They
test block and grid containers. We'll fix flex containers in the next part.
| Assignee | ||
Comment 9•1 year ago
|
||
| Assignee | ||
Comment 10•1 year ago
|
||
A sticky element gets its offsets computed in
StickyScrollContainer::ComputeStickyOffsets(), and that is invoked in
UpdateSticky() after we reflow the scrolled frame in
nsHTMLScrollFrame::Reflow().
Therefore, in the initial reflow of the sticky element (where we haven't fully
reflow its scrolled frame container), ComputePosition() does nothing because
the elements doesn't get its offsets computed yet [2].
In an incremental reflow of a sticky element, the code can produce wrong sticky
position, because ComputePosition() and its helper ComputeStickyLimits() use
an obsoleted scrollable overflow of the scrolled frame [3] or an obsoleted
offset [4] from the last reflow. For example, in the testcases the sticky offset
has a percentage value and its basis is changed (e.g. scroll container's width
or height changed).
To summarize, computing sticky position prematurely leads to issues, and doesn't
always prevent unnecessary overflow updates, both in the initial reflow and some
incremental reflow cases. Thus, this patch removes it, and always let the scroll
container update the positions for all sticky elements.
[1] https://searchfox.org/mozilla-central/rev/6121b33709dd80979a6806ff59096a561e348ae8/layout/generic/nsGfxScrollFrame.cpp#1624
[2] To be precise, ComputedOffsetProperty() is not set, and will bail out in
StickyScrollContainer::ComputeStickyLimits().
[3] https://searchfox.org/mozilla-central/rev/6121b33709dd80979a6806ff59096a561e348ae8/layout/generic/StickyScrollContainer.cpp#198
[4] https://searchfox.org/mozilla-central/rev/6121b33709dd80979a6806ff59096a561e348ae8/layout/generic/StickyScrollContainer.cpp#161-162
| Assignee | ||
Comment 11•1 year ago
|
||
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Comment 12•1 year ago
|
||
Comment 14•1 year ago
|
||
| bugherder | ||
https://hg.mozilla.org/mozilla-central/rev/b6ed0b385f41
https://hg.mozilla.org/mozilla-central/rev/8278ed498d02
https://hg.mozilla.org/mozilla-central/rev/1f2bdb707f16
Updated•1 year ago
|
Description
•