paged.html (4848B)
1 <!DOCTYPE html> 2 <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-type" /> 3 <title>Page scroll snapping</title> 4 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1"> 5 <meta name="flags" content="should"> 6 <meta name="assert" 7 content="Test passes if page operation doesn't skip content"> 8 9 <script src="/resources/testharness.js"></script> 10 <script src="/resources/testharnessreport.js"></script> 11 <script src="/resources/testdriver.js"></script> 12 <script src="/resources/testdriver-vendor.js"></script> 13 <script src="/resources/testdriver-actions.js"></script> 14 <script src="/dom/events/scrolling/scroll_support.js"></script> 15 <script src="../support/common.js"></script> 16 17 <style> 18 html, body { 19 margin: 0; 20 } 21 .scroller { 22 height: 100vh; 23 overflow: auto; 24 position: relative; 25 scroll-snap-type: y mandatory; 26 counter-reset: --page; 27 } 28 29 .gap { 30 height: 100vh; 31 } 32 33 .page { 34 counter-increment: --page; 35 height: 90vh; 36 scroll-snap-align: center; 37 padding: 8px; 38 position: relative; 39 --page: counter(--page); 40 } 41 .short { 42 height: 25vh; 43 } 44 .page > div::before { 45 content: "Page " counter(--page); 46 font-size: 1.5em; 47 } 48 .page > div { 49 box-sizing: border-box; 50 border: 3px solid black; 51 border-radius: 5px; 52 overflow: clip; /* Make sure font size doesn't cause pages to be larger than expected. */ 53 padding: 8px; 54 height: 100%; 55 } 56 </style> 57 <div class="scroller" tabindex="0"> 58 <div class="page"> 59 <div> 60 <p>This tests what happens when you perform a paging scroll (e.g. space bar or page down key) with mandatory scroll snap.</p> 61 <p>When snapped to this page, pressing page down should not skip page 2.</p> 62 </div> 63 </div> 64 <div class="short page"> 65 <div> 66 <p>This page should not be skipped by paging scroll operations.</p> 67 </div> 68 </div> 69 <div class="page"> 70 <div> 71 <p>We must stop at this page before going to page 4.</p> 72 </div> 73 </div> 74 <div class="short page"> 75 <div> 76 <p>Pages 4, 5, and 6 should be a single snap stop on page 5.</p> 77 </div> 78 </div> 79 <div class="short page"> 80 <div> 81 <p> 82 This should be the snapped page when paging. 83 The next page operation should jump to page 7. 84 </p> 85 </div> 86 </div> 87 <div class="short page"> 88 <div></div> 89 </div> 90 <div class="page"> 91 <div> 92 <p> 93 The next page is further than a page away, 94 but there are no closer snap points 95 so it should be scrolled to next. 96 </p> 97 </div> 98 </div> 99 <div class="gap"></div> 100 <div class="page"> 101 <div> 102 <p> 103 The last page 104 </p> 105 </div> 106 </div> 107 </div> 108 109 <script> 110 const scroller = document.querySelector(".scroller"); 111 112 scrollTop = () => scroller.scrollTop; 113 114 async function snapTo(page) { 115 if (page == 1 && scroller.scrollTop == 0) 116 return; 117 let scrollEndPromise = waitForScrollEndFallbackToDelayWithoutScrollEvent(scroller); 118 scroller.scrollTop = 0; 119 await scrollEndPromise; 120 if (page > 1) { 121 scrollEndPromise = waitForScrollEndFallbackToDelayWithoutScrollEvent(scroller); 122 scroller.querySelector(`.page[data-page="${page}"]`).scrollIntoView({block: "center"}); 123 await scrollEndPromise; 124 } 125 } 126 127 scroller.querySelectorAll('.page').forEach((div, index) => { 128 div.setAttribute("data-page", index + 1); 129 }); 130 function visiblePages() { 131 return Array.prototype.slice.apply( 132 scroller.querySelectorAll('.page')).filter( 133 div => div.offsetTop >= scroller.scrollTop && 134 div.offsetTop + div.offsetHeight <= scroller.scrollTop + scroller.clientHeight).map( 135 div => parseInt(div.getAttribute("data-page"))); 136 } 137 138 async function pageDown() { 139 const scrollEndPromise = waitForScrollEndFallbackToDelayWithoutScrollEvent(scroller); 140 await keyPress(scroller, "Space"); 141 await scrollEndPromise; 142 } 143 144 promise_test(async t => { 145 await snapTo(1); 146 assert_array_equals(visiblePages(), [1]); 147 await pageDown(); 148 assert_array_equals(visiblePages(), [2]); 149 }, `Doesn't skip past small snappable content`); 150 151 promise_test(async t => { 152 await snapTo(2); 153 assert_array_equals(visiblePages(), [2]); 154 await pageDown(); 155 assert_array_equals(visiblePages(), [3]); 156 }, `Doesn't skip past large snappable content`); 157 158 promise_test(async t => { 159 await snapTo(3); 160 assert_array_equals(visiblePages(), [3]); 161 await pageDown(); 162 assert_array_equals(visiblePages(), [4, 5, 6]); 163 }, `Scrolls multiple smaller items into view`); 164 165 promise_test(async t => { 166 await snapTo(5); 167 assert_array_equals(visiblePages(), [4, 5, 6]); 168 await pageDown(); 169 assert_array_equals(visiblePages(), [7]); 170 }, `Scrolls past items currently in view`); 171 172 promise_test(async t => { 173 await snapTo(7); 174 assert_array_equals(visiblePages(), [7]); 175 await pageDown(); 176 assert_array_equals(visiblePages(), [8]); 177 }, `Scrolls more than a page if necessary`); 178 179 </script>