1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#scroll-snap-stop" />
<link rel="help" href="https://drafts.csswg.org/css-scroll-snap-1/#snap-overflow" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
div {
position: absolute;
}
.scroller {
width: 400px;
height: 100px;
overflow: scroll;
scroll-snap-type: x mandatory;
}
#space {
left: 0px;
top: 0px;
width: 2100px;
height: 50px;
}
.target {
width: 50px;
height: 50px;
scroll-snap-align: start;
top: 0px;
}
</style>
<!--
start dest closest always
|------------------------------|--------|--------|
-->
<div class="scroller" id="scroller1">
<div id="space"></div>
<div class="target" style="left: 0px;"></div>
<!-- Add `scroll-snap-stop: always` element into the DOM tree prior to the
closest snap point -->
<div class="target" style="left: 120px; scroll-snap-stop: always;"></div>
<!-- Add a snap point closest-to-destination but further than the destination
from the start position -->
<div class="target" style="left: 110px;"></div>
</div>
<!--
start closest dest always
|------------------------------|------|--------|
-->
<div class="scroller" id="scroller2">
<div id="space"></div>
<div class="target" style="left: 0px;"></div>
<div class="target" style="left: 120px; scroll-snap-stop: always;"></div>
<!-- Add a snap point closest-to-destination and closer than the destination
from the start position -->
<div class="target" style="left: 95px;"></div>
</div>
</div>
<!--
A test case where there's a snap point whose snap area covers the snapport and
there's a `scroll-snap-stop: always` snap point on the opposite side.
-->
<div class="scroller" id="scroller3">
<div id="space"></div>
<div class="target" style="left: 0px;"></div>
<div class="target" style="left: 700px; scroll-snap-stop: always;"></div>
<!-- Add a snap point where the snap area covers the snapport entirely -->
<div class="target" style="left: 100px; width: 500px;"></div>
<!-- Add a snap point where the distance between this and the 100px point is
larger than the snapport size (400px) -->
<div class="target" style="left: 600px;"></div>
</div>
<!--
A similar case above, but two `scroll-snap-stop: always` snap points.
-->
<div class="scroller" id="scroller4">
<div id="space"></div>
<div class="target" style="left: 0px;"></div>
<div class="target" style="left: 700px; scroll-snap-stop: always;"></div>
<!-- Add a snap point where the snap area covers the snapport entirely -->
<div class="target" style="left: 100px; width: 500px;"></div>
<!-- Add a snap point where the distance between this and the 100px point is
larger than the snapport size (400px) -->
<div class="target" style="left: 600px; scroll-snap-stop: always;"></div>
</div>
<!--
Another similar case, but the nearest snap point to the start point is
`scroll-snap-stop: always`.
-->
<div class="scroller" id="scroller5">
<div id="space"></div>
<div class="target" style="left: 0px;"></div>
<div class="target" style="left: 700px; scroll-snap-stop: always;"></div>
<!-- Add a snap point where the snap area covers the snapport entirely -->
<div class="target" style="left: 100px; width: 500px; scroll-snap-stop: always;"></div>
<!-- Add a snap point where the distance between this and the 100px point is
larger than the snapport size (400px) -->
<div class="target" style="left: 600px;"></div>
</div>
<!--
A test case that a `scroll-snap-stop: always` snap point is further than the
scroll destination.
-->
<div class="scroller" id="scroller6">
<div id="space"></div>
<div class="target" style="left: 0px;"></div>
<div class="target" style="left: 400px;"></div>
<div class="target" style="left: 700px; scroll-snap-stop: always;"></div
</div>
<script>
test(() => {
assert_equals(scroller1.scrollLeft, 0);
assert_equals(scroller1.scrollTop, 0);
// start dest closest always
// |------------------------------|--------|--------|
// 0 100 110 120
scroller1.scrollBy(100, 0);
assert_equals(scroller1.scrollLeft, 110);
assert_equals(scroller1.scrollTop, 0);
}, "The closest snap point is preferred than scroll-snap-stop: always where " +
"it's further than the destination (the closest one is closer to the " +
"scroll start position than the destination)");
test(() => {
assert_equals(scroller2.scrollLeft, 0);
assert_equals(scroller2.scrollTop, 0);
// start closest dest always
// |------------------------------|------|--------|
// 0 95 100 120
scroller2.scrollBy(100, 0);
assert_equals(scroller2.scrollLeft, 95);
assert_equals(scroller2.scrollTop, 0);
}, "The closest snap point is preferred than scroll-snap-stop: always where " +
"it's further than the destination (the closest one is futrher than the " +
"destination from the start position)");
test(() => {
assert_equals(scroller3.scrollLeft, 0);
assert_equals(scroller3.scrollTop, 0);
// start dest always
// |-----|===|============================|------|
// 0 100 150 600 700
// Scoll on the element whose snap area is larger than the snapport.
scroller3.scrollBy(150, 0);
assert_equals(scroller3.scrollLeft, 150);
assert_equals(scroller3.scrollTop, 0);
}, "The scroll destination on a large element whose snap area covers " +
"the snapport entirely is a valid snap position");
test(() => {
assert_equals(scroller4.scrollLeft, 0);
assert_equals(scroller4.scrollTop, 0);
// start dest always always
// |-----|====|============================|------|
// 0 100 150 600 700
// Scoll on the element whose snap area is larger than the snapport.
scroller4.scrollBy(150, 0);
assert_equals(scroller4.scrollLeft, 150);
assert_equals(scroller4.scrollTop, 0);
}, "The scroll destination on a large element whose snap area covers " +
"the snapport entirely is a valid snap position (with two " +
"`scroll-snap-stop: always` snap points");
test(() => {
assert_equals(scroller5.scrollLeft, 0);
assert_equals(scroller5.scrollTop, 0);
// start always dest always
// |-----|=====|============================|------|
// 0 100 150 600 700
// Scoll on the element whose snap area is larger than the snapport, but
// the scroll-snap-stop property is `always`.
scroller5.scrollBy(150, 0);
assert_equals(scroller5.scrollLeft, 100);
assert_equals(scroller5.scrollTop, 0);
// Scroll the direction further, it should NOT be trapped by the
// `scroll-snap-stop: always` snap point.
scroller5.scrollBy(50, 0);
assert_equals(scroller5.scrollLeft, 150);
assert_equals(scroller5.scrollTop, 0);
}, "`scroll-snap-stop: always` snap point is preferred even if the snap area " +
"entire snapport");
test(() => {
assert_equals(scroller6.scrollLeft, 0);
assert_equals(scroller6.scrollTop, 0);
// start dest always
// |-------------------------|-----------------|------|
// 0 400 600 700
// Scroll to a point where it's closer to a `scroll-snap-stop: always` snap
// position.
scroller6.scrollBy(600, 0);
assert_equals(scroller6.scrollLeft, 700);
assert_equals(scroller6.scrollTop, 0);
}, "`scroll-snap-stop: always` snap point is further than the scroll " +
"destination");
</script>
|