<!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>