snapped-scrolled-content-2.html (5088B)
1 <!DOCTYPE html> 2 <html class="reftest-wait" reftest-zoom="1.2"> 3 <meta charset="utf-8"> 4 <title>Snapped rendering of scrolled contents, with a 120% zoom applied</title> 5 6 <!-- This file is identical to snapped-scrolled-content-1.html, except that 7 all the layout sizes have been divided by 1.2 so that, once the 120% 8 zoom is applied, it looks identical to snapped-scrolled-content-1.html. --> 9 10 <style> 11 12 body { 13 margin: 0; 14 padding: 50px; 15 font-size: 20px; 16 } 17 18 #scrollArea { 19 width: 300px; 20 overflow: auto; 21 scrollbar-width: none; 22 background: red; 23 outline: 1px solid black; 24 } 25 26 #scrolledContent { 27 position: relative; 28 background: white; 29 } 30 31 #line { 32 height: 1px; 33 background-color: black; 34 margin-bottom: -1px; 35 } 36 37 #boxWrapper { 38 display: flex; 39 flex-flow: row nowrap; 40 justify-content: space-around; 41 } 42 43 #boxWrapper > div { 44 width: 50px; 45 height: 50px; 46 box-sizing: border-box; 47 } 48 49 #box1 { 50 margin-top: -0.25px; 51 border: 1px solid red; 52 } 53 54 #box2 { 55 border: 1px solid green; 56 } 57 58 #box3 { 59 margin-top: 0.25px; 60 border: 1px solid blue; 61 } 62 63 #scrollIntoViewTarget { 64 position: absolute; 65 left: 0; 66 width: 0; 67 } 68 69 </style> 70 71 <div id="scrollArea"> 72 <div id="scrolledContent"> 73 <div id="topSpacer"></div> 74 <div id="line"></div> 75 <div id="boxWrapper"> 76 <div id="box1"></div> 77 <div id="box2"></div> 78 <div id="box3"></div> 79 </div> 80 <div id="scrollIntoViewTarget"></div> 81 </div> 82 </div> 83 84 <script> 85 86 function getFloatQueryParams(defaultValues) { 87 const result = Object.assign({}, defaultValues); 88 const searchParams = new URLSearchParams(location.search); 89 for (const [key, value] of searchParams) { 90 result[key] = parseFloat(value); 91 } 92 return result; 93 } 94 95 const params = getFloatQueryParams({ 96 top: 0, 97 topSpace: 80, 98 outerBottom: 160, 99 innerBottom: 200, 100 scrollIntoViewPos: null, 101 scrollTop: null, 102 text: null, 103 }); 104 105 const scrollArea = document.getElementById("scrollArea"); 106 const scrolledContent = document.getElementById("scrolledContent"); 107 const topSpacer = document.getElementById("topSpacer"); 108 const scrollIntoViewTarget = document.getElementById("scrollIntoViewTarget"); 109 110 scrollArea.style.marginTop = params.top + "px"; 111 topSpacer.style.height = (params.topSpace - params.top) + "px"; 112 scrollArea.style.height = (params.outerBottom - params.top) + "px"; 113 scrolledContent.style.height = (params.innerBottom - params.top) + "px"; 114 115 // Make sure the scroll frame has a display port. 116 scrollArea.scrollTop = 1; 117 scrollArea.scrollTop = 2; 118 scrollArea.scrollTop = 0; 119 120 if (params.text) { 121 box1.innerText = "text"; 122 box2.innerText = "text"; 123 box3.innerText = "text"; 124 } 125 126 function performScroll() { 127 if (params.scrollIntoViewPos !== null) { 128 // Scroll using `scrollIntoView`. 129 // At the time this test was written (2024-09-05), this way of calling scrollIntoView 130 // causes a ScrollTo call which doesn't allow any adjustment of the target scroll 131 // position for pixel alignment. This exercises "unsnapped" scrolling even if 132 // layout.disable-pixel-alignment is false. It also lets you scroll to 133 // fractional CSS positions, unlike scrollTop or scrollTo(). 134 const scrollIntoViewTarget = document.getElementById("scrollIntoViewTarget"); 135 scrollIntoViewTarget.style.top = params.scrollIntoViewPos + "px"; 136 scrollIntoViewTarget.style.height = (params.outerBottom - params.top) + "px"; 137 scrollIntoViewTarget.scrollIntoView(); 138 } else if (params.scrollTop !== null) { 139 // Scroll to params.scrollTop using the scrollTop property. 140 // At the time this test was written (2024-09-05), this property only accepts integers in Firefox. 141 // Since this test runs with a 1.2x zoom applied, the integer CSS pixel scroll 142 // position will cause a scrollTop * 1.2 device pixel offset of the contents. 143 // At the time this test was written, if layout.disable-pixel-alignment 144 // is false, Gecko will try to make it so that this device pixel offset is an 145 // integer number. 146 // For example, when setting scrollTop to 4, which would correspond to a device 147 // pixel offset of 4.8 device pixels, Gecko will instead set the internal offset 148 // to 4.16666667 CSS pixels, which corresponds to an integer offset of 5 device 149 // pixels. This is valid because, even if the true internal offset is 4.16666667 150 // CSS pixels, querying scrollTop will return the integer value 4, which matches 151 // the value that was set. 152 // In the future, scrollTop should accept and return floating point values, and 153 // the layout offset should match what was set. However, by that time, hopefully 154 // rendering will have changed such that the reftests which use this file still 155 // pass. 156 scrollArea.scrollTop = params.scrollTop; 157 } 158 159 document.documentElement.removeAttribute('class'); 160 } 161 162 // Perform the scroll once the reftest-zoom has been applied. 163 document.addEventListener("MozReftestInvalidate", performScroll); 164 165 </script>