scroll-marker-selection-in-padded-scroller.html (5557B)
1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta charset="utf-8"> 6 <title>CSS Test: scroll tracking for ::scroll-markers when scroll containers has large padding </title> 7 <link rel="help" href="https://drafts.csswg.org/css-overflow-5/#scroll-marker-pseudo"> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 <script src="/resources/testdriver.js"></script> 11 <script src="/resources/testdriver-actions.js"></script> 12 <script src="/resources/testdriver-vendor.js"></script> 13 <script src="support/scroll-marker-support.js"></script> 14 <script src="/dom/events/scrolling/scroll_support.js"></script> 15 </head> 16 17 <body> 18 <style> 19 .wrapper { 20 display: grid; 21 justify-content: center; 22 } 23 24 .carousel { 25 display: grid; 26 grid-auto-flow: column; 27 width: 1600px; 28 height: 512px; 29 overflow-x: scroll; 30 scroll-snap-type: x mandatory; 31 list-style-type: none; 32 scroll-behavior: smooth; 33 border: solid 2px grey; 34 padding-top: 10%; 35 text-align: center; 36 counter-set: markeridx; 37 38 &>.item { 39 scroll-snap-align: center; 40 height: 80%; 41 width: 318px; 42 border: 1px solid; 43 place-content: center; 44 45 &::scroll-marker { 46 content: counter(markeridx); 47 counter-increment: markeridx; 48 align-content: center; 49 text-align: center; 50 width: 35px; 51 height: 35px; 52 border: 3px solid gray; 53 border-radius: 50%; 54 margin: 3px; 55 background-color: red; 56 } 57 58 &::scroll-marker:target-current { 59 background-color: green; 60 } 61 } 62 63 &>.padding { 64 width: 1600px; 65 height: 90%; 66 border: solid 1px green; 67 } 68 69 scroll-marker-group: after; 70 71 &::scroll-marker-group { 72 height: 45px; 73 display: flex; 74 align-items: center; 75 justify-content: center; 76 border: solid 1px black; 77 border-radius: 30px; 78 } 79 } 80 </style> 81 <div class="wrapper"> 82 <div class="carousel" id="carousel"> 83 <div class="padding"></div> 84 <div class="item" tabindex=0>1</div> 85 <div class="item" tabindex=0>2</div> 86 <div class="item" tabindex=0>3</div> 87 <div class="item" tabindex=0>4</div> 88 <div class="item" tabindex=0>5</div> 89 <div class="item" tabindex=0>6</div> 90 <div class="item" tabindex=0>7</div> 91 <div class="item" tabindex=0>8</div> 92 <div class="item" tabindex=0>9</div> 93 <div class="item" tabindex=0>10</div> 94 <div class="item" tabindex=0>11</div> 95 <div class="item" tabindex=0>12</div> 96 <div class="item" tabindex=0>13</div> 97 <div class="item" tabindex=0>14</div> 98 <div class="item" tabindex=0>15</div> 99 <div class="item" tabindex=0>16</div> 100 <div class="padding"></div> 101 </div> 102 </div> 103 <script> 104 const carousel = document.getElementById("carousel"); 105 const items = carousel.querySelectorAll(".item"); 106 107 RED = "rgb(255, 0, 0)"; 108 GREEN = "rgb(0, 128, 0)"; 109 110 let current_expected_marker_idx = null; 111 let current_request_id = null; 112 113 function watchFrames() { 114 current_request_id = requestAnimationFrame(() => { 115 if (current_expected_marker_idx !== null) { 116 verifySelectedMarker(current_expected_marker_idx, items, GREEN, RED); 117 } 118 current_request_id = requestAnimationFrame(watchFrames); 119 }); 120 } 121 122 // The distribute range[1] is a portion of the scroll range in which we 123 // determine the active scroll-marker in a way that accounts for unreachable 124 // scroll targets[2]. 125 // This tests what happens when we scroll into the distribute range in a 126 // layout scenario where (because of the padding) there is no scroll target 127 // in the distribute range. 128 // [1] https://drafts.csswg.org/css-overflow-5/#:~:text=distribute%20range 129 // [2] https://github.com/w3c/csswg-drafts/issues/11165 130 async function scroll_test(t, scrollAmount) { 131 await waitForCompositorCommit(); 132 const initial_offset = carousel.scrollLeft; 133 134 // Watch every frame, verifying the selected marker. 135 watchFrames(); 136 137 const scrollend_promise = 138 waitForScrollEndFallbackToDelayWithoutScrollEvent(carousel); 139 const actions_promise = new test_driver.Actions().scroll(0, 0, 140 scrollAmount, 0, { origin: carousel }).send(); 141 142 await Promise.all([actions_promise, scrollend_promise]); 143 144 assert_equals(carousel.scrollLeft, initial_offset, 145 "carousel is snapped back to initial position."); 146 cancelAnimationFrame(current_request_id); 147 148 current_expected_marker_idx = null; 149 current_request_id = null; 150 } 151 152 promise_test(async (t) => { 153 await waitForCompositorCommit(); 154 current_expected_marker_idx = 0; 155 // Scroll left padding into view. 156 const scrollAmount = -carousel.clientWidth; 157 await scroll_test(t, scrollAmount); 158 verifySelectedMarker(0, items, GREEN, RED); 159 }, "scroll-marker selection at left edge with padding"); 160 161 promise_test(async (t) => { 162 await waitForCompositorCommit(); 163 await waitForScrollReset(t, carousel, carousel.scrollWidth, 0); 164 current_expected_marker_idx = 15; 165 // Scroll right padding into view. 166 const scrollAmount = carousel.clientWidth; 167 await scroll_test(t, scrollAmount); 168 verifySelectedMarker(15, items, GREEN, RED); 169 }, "scroll-marker selection at right edge with padding"); 170 </script> 171 </body> 172 173 </html>