Toggling overflow on an ancestor fires a spurious scroll event on a scrolled descendant
Categories
(Core :: Layout: Scrolling and Overflow, defect, P3)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox158 | --- | fixed |
People
(Reporter: dao, Assigned: hiro)
References
(Blocks 1 open bug)
Details
Attachments
(2 files, 1 obsolete file)
Setting and then removing overflow on an ancestor of a scrolled element dispatches a scroll event on that element, though its scroll position and every metric are unchanged. Per spec scroll fires when the scroll position changes, so nothing should fire here.
Testcase:
<div id="host">
<div id="scroller" style="height:100px;overflow-y:auto">
<div style="height:2000px"></div>
</div>
</div>
STR:
scroller.scrollTop = 50, let it settlehost.style.overflow = "hidden", read layout,host.style.removeProperty("overflow"), read layout- Wait a frame
Actual: one scroll event on #scroller. scrollTop, clientHeight, scrollHeight and the host's height are identical before, during and after.
Expected: no scroll event.
Only overflow does it -- overflow: clip, background-color and contain: paint, set and removed the same way, fire nothing. The frame reconstruction from the ancestor becoming a scroll container looks like the trigger.
Bug 2066403 is a consumer that hit this: panel-list sets overflow: hidden on its parent while it measures for positioning, and its own scroll-to-hide listener reads the resulting event as the anchor moving, closing the menu it just opened.
| Reporter | ||
Comment 1•27 days ago
|
||
Open in Firefox; the table fills itself in on load. Each row scrolls #scroller to 50, lets it settle, then sets and removes one property on its ancestor #host and counts scroll events on #scroller.
Firefox 156.0a1 (local opt build):
| set on #host, then removed | scroll events | metrics unchanged |
|---|---|---|
overflow: hidden |
1 | yes |
overflow: clip |
0 | yes |
overflow: scroll |
1 | yes |
background-color: red |
0 | yes |
contain: paint |
0 | yes |
So it is the ancestor becoming a scroll container that does it: hidden and scroll both fire one event, clip -- which clips without creating a scroll container -- fires none. scrollTop, clientHeight and scrollHeight are identical before, during and after in every row.
Updated•21 days ago
|
| Assignee | ||
Comment 2•11 days ago
|
||
ScrollToRestoredPosition re-establishes a position the content already had,
either across a frame reconstruction or from session history. Nothing is
scrolled, so the scrolling events shouldn't run. Chrome fires nothing in
either case.
Updated•11 days ago
|
| Assignee | ||
Comment 3•10 days ago
|
||
A reconstruction re-establishes a position the content already had, so nothing
scrolled and the scrolling events shouldn't run. Chrome fires nothing there
either.
Session history restore keeps firing, so the restore reason has to reach
ScrollToRestoredPosition: both restores go through the docShell's
nsILayoutHistoryState, and ScrollOrigin::Restore alone cannot tell them apart.
Updated•10 days ago
|
Updated•10 days ago
|
Updated•10 days ago
|
| Reporter | ||
Updated•10 days ago
|
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/62661 for changes under testing/web-platform/tests
Upstream PR merged by moz-wptsync-bot
Description
•