snapped-scrolled-content-1.html (3582B)
1 <!DOCTYPE html> 2 <html class="reftest-wait"> 3 <meta charset="utf-8"> 4 <title>Snapped rendering of scrolled contents</title> 5 6 <style> 7 8 body { 9 margin: 0; 10 padding: 60px; 11 font-size: 24px; 12 } 13 14 #scrollArea { 15 width: 360px; 16 overflow: auto; 17 scrollbar-width: none; 18 background: red; 19 outline: 1px solid black; 20 } 21 22 #scrolledContent { 23 position: relative; 24 background: white; 25 } 26 27 #line { 28 height: 1px; 29 background-color: black; 30 margin-bottom: -1px; 31 } 32 33 #boxWrapper { 34 display: flex; 35 flex-flow: row nowrap; 36 justify-content: space-around; 37 } 38 39 #boxWrapper > div { 40 width: 60px; 41 height: 60px; 42 box-sizing: border-box; 43 } 44 45 #box1 { 46 margin-top: -0.3px; 47 border: 1px solid red; 48 } 49 50 #box2 { 51 border: 1px solid green; 52 } 53 54 #box3 { 55 margin-top: 0.3px; 56 border: 1px solid blue; 57 } 58 59 #scrollIntoViewTarget { 60 position: absolute; 61 left: 0; 62 width: 0; 63 } 64 65 </style> 66 67 <div id="scrollArea"> 68 <div id="scrolledContent"> 69 <div id="topSpacer"></div> 70 <div id="line"></div> 71 <div id="boxWrapper"> 72 <div id="box1"></div> 73 <div id="box2"></div> 74 <div id="box3"></div> 75 </div> 76 <div id="scrollIntoViewTarget"></div> 77 </div> 78 </div> 79 80 <script> 81 82 function getFloatQueryParams(defaultValues) { 83 const result = Object.assign({}, defaultValues); 84 const searchParams = new URLSearchParams(location.search); 85 for (const [key, value] of searchParams) { 86 result[key] = parseFloat(value); 87 } 88 return result; 89 } 90 91 const params = getFloatQueryParams({ 92 top: 0, 93 topSpace: 96, 94 outerBottom: 192, 95 innerBottom: 240, 96 scrollIntoViewPos: null, 97 scrollTop: null, 98 text: null, 99 }); 100 101 const scrollArea = document.getElementById("scrollArea"); 102 const scrolledContent = document.getElementById("scrolledContent"); 103 const topSpacer = document.getElementById("topSpacer"); 104 105 scrollArea.style.marginTop = params.top + "px"; 106 topSpacer.style.height = (params.topSpace - params.top) + "px"; 107 scrollArea.style.height = (params.outerBottom - params.top) + "px"; 108 scrolledContent.style.height = (params.innerBottom - params.top) + "px"; 109 110 // Make sure the scroll frame has a display port. 111 scrollArea.scrollTop = 1; 112 scrollArea.scrollTop = 2; 113 scrollArea.scrollTop = 0; 114 115 if (params.text) { 116 box1.innerText = "text"; 117 box2.innerText = "text"; 118 box3.innerText = "text"; 119 } 120 121 function performScroll() { 122 if (params.scrollIntoViewPos !== null) { 123 // Scroll using `scrollIntoView`. 124 // At the time this test was written (2024-09-05), this way of calling scrollIntoView 125 // causes a ScrollTo call which doesn't allow any adjustment of the target scroll 126 // position for pixel alignment. This exercises "unsnapped" scrolling even if 127 // layout.disable-pixel-alignment is false. It also lets you scroll to 128 // fractional CSS positions, unlike scrollTop or scrollTo(). 129 const scrollIntoViewTarget = document.getElementById("scrollIntoViewTarget"); 130 scrollIntoViewTarget.style.top = params.scrollIntoViewPos + "px"; 131 scrollIntoViewTarget.style.height = (params.outerBottom - params.top) + "px"; 132 scrollIntoViewTarget.scrollIntoView(); 133 } else if (params.scrollTop !== null) { 134 // Scroll to params.scrollTop using the scrollTop property. 135 // At the time this test was written (2024-09-05), this property only accepts integers in Firefox. 136 scrollArea.scrollTop = params.scrollTop; 137 } 138 139 document.documentElement.removeAttribute('class'); 140 } 141 142 document.addEventListener("MozReftestInvalidate", performScroll); 143 144 </script>