Skip to content

Commit 8e013fb

Browse files
hiikezoefoolip
authored andcommitted
Do not set any snap target id for candidate snap points on elements larger than the snapport size.
In Gecko scroll snap id is a raw pointer of each snap target element. So if the snap target element is larger than the snapport and once after we snapped to a point inside element but the point is away from the element's `scroll-snap-align` point, the snap id forces us to snap to the element's `scroll-snap-align` point when we try to re-snap. Differential Revision: https://phabricator.services.mozilla.com/D258498 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1978946 gecko-commit: dd0ed736e4dfac78a30ef5d4f5a47e141c723b78 gecko-reviewers: botond
1 parent 38dbf04 commit 8e013fb

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!DOCTYPE html>
2+
<meta name="viewport" content="width=device-width,initial-scale=1">
3+
<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap" />
4+
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1978946">
5+
<script src="/resources/testharness.js"></script>
6+
<script src="/resources/testharnessreport.js"></script>
7+
<style>
8+
#scroller {
9+
overflow-y: auto;
10+
scroll-snap-type: y mandatory;
11+
width: 100vw;
12+
height: calc(100svh - 80px);
13+
}
14+
.child {
15+
scroll-snap-align: start;
16+
scroll-snap-stop: always;
17+
width: 100%;
18+
height: calc(100svh - 80px);
19+
font-size: 30px;
20+
}
21+
.child:last-child {
22+
background-image: linear-gradient(to right, black 1px, transparent 1px),
23+
linear-gradient(to bottom, black 1px, transparent 1px);
24+
background-size: 64px 64px;
25+
height: 200%;
26+
}
27+
</style>
28+
<div id="scroller">
29+
<div class="child">1</div>
30+
<div class="child">2</div>
31+
</div>
32+
<script>
33+
promise_test(async () => {
34+
assert_equals(scroller.scrollTop, 0);
35+
36+
const scrollendPromise = new Promise(resolve => {
37+
scroller.addEventListener("scrollend", resolve);
38+
});
39+
40+
const expectedPosition =
41+
scroller.children[0].getBoundingClientRect().height + 100;
42+
// Try to scroll downward, it will snap to a position inside
43+
// the second child.
44+
scroller.scrollTo(0, expectedPosition);
45+
await scrollendPromise;
46+
47+
assert_equals(scroller.scrollTop, expectedPosition,
48+
"The scroll position is the expected one");
49+
50+
// Change the second child width, it will re-evaluate the snap position.
51+
scroller.querySelector(":last-child").style.width = "99%";
52+
53+
// Give a chance to scroll if it happens.
54+
await new Promise(resolve => {
55+
requestAnimationFrame(() => requestAnimationFrame(resolve));
56+
});
57+
58+
assert_equals(scroller.scrollTop, expectedPosition,
59+
"Should stay at the last snap point");
60+
}, "Keep the same snap position on overflowing-snap-area when re-snapping");
61+
</script>

0 commit comments

Comments
 (0)