position-absolute-replaced-minmax.html (15396B)
1 <!DOCTYPE html> 2 <title>CSS Position: absolute position, replaced elements, and minmax</title> 3 <link rel="author" title="mailto:atotic@google.com"> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <link rel="help" href="https://www.w3.org/TR/CSS2/visudet.html#min-max-widths"> 7 <meta name="assert" content="Min/max width and height interact properly with abspos replaced elements"> 8 <style> 9 .container { 10 position: relative; 11 display: inline-block; 12 width: 400px; 13 height: 200px; 14 border: 1px solid black; 15 } 16 .target { 17 position: absolute; 18 padding: 10px; 19 bottom: 0; 20 right: 0; 21 border-width: 3px 7px 9px 11px; 22 border-color: yellow; 23 border-style: solid; 24 margin: 1px 3px 7px 9px; 25 } 26 </style> 27 <!-- test all combinations of minmax from section 10.4 table at 28 https://www.w3.org/TR/CSS2/visudet.html#min-max-widths --> 29 30 <!-- IFRAME tests --> 31 <!-- iframe: intrinsic size is 300x150, no aspect ratio --> 32 <div class="container"> 33 <iframe class="target" 34 data-expected-width="338" data-expected-height="182" data-offset-y="11" data-offset-x="59" 35 > 36 </iframe> 37 </div> 38 <!-- spec 1: w > max-width --> 39 <div class="container"> 40 <iframe class="target" style="max-width:100px" 41 data-expected-width="138" data-expected-height="182" data-offset-y="11" data-offset-x="259" 42 > 43 </iframe> 44 </div> 45 <!-- spec 2: w < min-width --> 46 <div class="container"> 47 <iframe class="target" style="min-width: 350px" 48 data-expected-width="388" data-expected-height="182" data-offset-y="11" data-offset-x="9" 49 > 50 </iframe> 51 </div> 52 <!-- spec 3: h > max-height --> 53 <div class="container"> 54 <iframe class="target" style="max-height: 150px" 55 data-expected-width="338" data-expected-height="182" data-offset-y="11" data-offset-x="59" 56 > 57 </iframe> 58 </div> 59 <!-- spec 4: h < min-height --> 60 <div class="container"> 61 <iframe class="target" style="min-height: 165px" 62 data-expected-width="338" data-expected-height="197" data-offset-y="-4" data-offset-x="59" 63 > 64 </iframe> 65 </div> 66 <!-- spec 5: (w > max-width) and (h > max-height), where (max-width/w ≤ max-height/h) --> 67 <div class="container"> 68 <iframe class="target" style="max-width: 240px; max-height: 135px" 69 data-expected-width="278" data-expected-height="167" data-offset-y="26" data-offset-x="119" 70 > 71 </iframe> 72 </div> 73 <!-- spec 6: (w > max-width) and (h > max-height), where (max-width/w > max-height/h) --> 74 <div class="container"> 75 <iframe class="target" style="max-width: 270px; max-height: 120px" 76 data-expected-width="308" data-expected-height="152" data-offset-y="41" data-offset-x="89" 77 > 78 </iframe> 79 </div> 80 <!-- spec 7: (w < min-width) and (h < min-height), where (min-width/w ≤ min-height/h) --> 81 <div class="container"> 82 <iframe class="target" style="min-width: 360px; min-height: 165px" 83 data-expected-width="398" data-expected-height="197" data-offset-y="-4" data-offset-x="-1" 84 > 85 </iframe> 86 </div> 87 <!-- spec 8: (w < min-width) and (h < min-height), where (min-width/w > min-height/h) --> 88 <div class="container"> 89 <iframe class="target" style="min-width: 330px; min-height: 180px" 90 data-expected-width="368" data-expected-height="212" data-offset-y="-19" data-offset-x="29" 91 > 92 </iframe> 93 </div> 94 <!-- spec 9: (w < min-width) and (h > max-height) --> 95 <div class="container"> 96 <iframe class="target" style="min-width: 330px; max-height: 135px" 97 data-expected-width="368" data-expected-height="167" data-offset-y="26" data-offset-x="29" 98 > 99 </iframe> 100 </div> 101 <!-- spec 10: (w > max-width) and (h < min-height) --> 102 <div class="container"> 103 <iframe class="target" style="max-width: 240px; min-height: 165px" 104 data-expected-width="278" data-expected-height="197" data-offset-y="-4" data-offset-x="119" 105 > 106 </iframe> 107 </div> 108 109 <!-- IMG png tests --> 110 <!-- image dimensions: 200x150. images has intrinic size and aspect ratio --> 111 <div class="container"> 112 <img class="target png" 113 data-expected-width="238" data-expected-height="182" data-offset-y="11" data-offset-x="159" 114 > 115 </div> 116 <!-- spec 1: w > max-width --> 117 <div class="container"> 118 <img class="target png" style="max-width: 180px" 119 data-expected-width="218" data-expected-height="167" data-offset-y="26" data-offset-x="179" 120 > 121 </div> 122 <!-- spec 2: w < min-width --> 123 <div class="container"> 124 <img class="target png" style="min-width: 220px" 125 data-expected-width="258" data-expected-height="197" data-offset-y="-4" data-offset-x="139" 126 > 127 </div> 128 129 <!-- spec 3: h > max-height --> 130 <div class="container"> 131 <img class="target png" style="max-height: 135px" 132 data-expected-width="218" data-expected-height="167" data-offset-y="26" data-offset-x="179" 133 > 134 </div> 135 <!-- spec 4: h < min-height --> 136 <div class="container"> 137 <img class="target png" style="min-height: 165px" 138 data-expected-width="258" data-expected-height="197" data-offset-y="-4" data-offset-x="139" 139 > 140 </div> 141 <!-- spec 5: (w > max-width) and (h > max-height), where (max-width/w ≤ max-height/h) --> 142 <div class="container"> 143 <img class="target png" style="max-width: 160px; max-height: 135px" 144 data-expected-width="198" data-expected-height="152" data-offset-y="41" data-offset-x="199" 145 > 146 </div> 147 <!-- spec 6: (w > max-width) and (h > max-height), where (max-width/w > max-height/h) --> 148 <div class="container"> 149 <img class="target png" style="max-width: 180px; max-height: 120px" 150 data-expected-width="198" data-expected-height="152" data-offset-y="41" data-offset-x="199" 151 > 152 </div> 153 <!-- spec 7: (w < min-width) and (h < min-height), where (min-width/w ≤ min-height/h) --> 154 <div class="container"> 155 <img class="target png" style="min-width: 240px;min-height: 165px" 156 data-expected-width="278" data-expected-height="212" data-offset-y="-19" data-offset-x="119" 157 > 158 </div> 159 <!-- spec 8: (w < min-width) and (h < min-height), where (min-width/w > min-height/h) --> 160 <div class="container"> 161 <img class="target png" style="min-width: 220px;min-height: 180px" 162 data-expected-width="278" data-expected-height="212" data-offset-y="-19" data-offset-x="119" 163 > 164 </div> 165 <!-- spec 9: (w < min-width) and (h > max-height) --> 166 <div class="container"> 167 <img class="target png" style="min-width: 220px; max-height: 130px" 168 data-expected-width="258" data-expected-height="162" data-offset-y="31" data-offset-x="139" 169 > 170 </div> 171 <!-- spec 10: (w > max-width) and (h < min-height) --> 172 <div class="container"> 173 <img class="target png" style="max-width: 180px; min-height: 165px" 174 data-expected-width="218" data-expected-height="197" data-offset-y="-4" data-offset-x="179" 175 > 176 </div> 177 <!-- IMG SVG tests --> 178 <!-- image dimensions: 200x150. images has no intrinic size and no aspect ratio --> 179 <div class="container"> 180 <img class="target svg" 181 data-expected-width="338" data-expected-height="182" data-offset-y="11" data-offset-x="59" 182 > 183 </div> 184 <!-- spec 1: w > max-width --> 185 <div class="container"> 186 <img class="target svg" style="max-width: 180px" 187 data-expected-width="218" data-expected-height="182" data-offset-y="11" data-offset-x="179" 188 > 189 </div> 190 <!-- spec 2: w < min-width --> 191 <div class="container"> 192 <img class="target svg" style="min-width: 220px" 193 data-expected-width="338" data-expected-height="182" data-offset-y="11" data-offset-x="59" 194 > 195 </div> 196 197 <!-- spec 3: h > max-height --> 198 <div class="container"> 199 <img class="target svg" style="max-height: 135px" 200 data-expected-width="338" data-expected-height="167" data-offset-y="26" data-offset-x="59" 201 > 202 </div> 203 <!-- spec 4: h < min-height --> 204 <div class="container"> 205 <img class="target svg" style="min-height: 165px" 206 data-expected-width="338" data-expected-height="197" data-offset-y="-4" data-offset-x="59" 207 > 208 </div> 209 <!-- spec 5: (w > max-width) and (h > max-height), where (max-width/w ≤ max-height/h) --> 210 <div class="container"> 211 <img class="target svg" style="max-width: 160px; max-height: 135px" 212 data-expected-width="198" data-expected-height="167" data-offset-y="26" data-offset-x="199" 213 > 214 </div> 215 <!-- spec 6: (w > max-width) and (h > max-height), where (max-width/w > max-height/h) --> 216 <div class="container"> 217 <img class="target svg" style="max-width: 180px; max-height: 120px" 218 data-expected-width="218" data-expected-height="152" data-offset-y="41" data-offset-x="179" 219 > 220 </div> 221 <!-- spec 7: (w < min-width) and (h < min-height), where (min-width/w ≤ min-height/h) --> 222 <div class="container"> 223 <img class="target svg" style="min-width: 240px;min-height: 165px" 224 data-expected-width="338" data-expected-height="197" data-offset-y="-4" data-offset-x="59" 225 > 226 </div> 227 <!-- spec 8: (w < min-width) and (h < min-height), where (min-width/w > min-height/h) --> 228 <div class="container"> 229 <img class="target svg" style="min-width: 220px;min-height: 180px" 230 data-expected-width="338" data-expected-height="212" data-offset-y="-19" data-offset-x="59" 231 > 232 </div> 233 <!-- spec 9: (w < min-width) and (h > max-height) --> 234 <div class="container"> 235 <img class="target svg" style="min-width: 220px; max-height: 130px" 236 data-expected-width="338" data-expected-height="162" data-offset-y="31" data-offset-x="59" 237 > 238 </div> 239 <!-- spec 10: (w > max-width) and (h < min-height) --> 240 <div class="container"> 241 <img class="target svg" style="max-width: 180px; min-height: 165px" 242 data-expected-width="218" data-expected-height="197" data-offset-y="-4" data-offset-x="179" 243 > 244 </div> 245 <!-- SVG tests --> 246 <!-- SVGs are special: any combination of intrinsic_size and aspect_ratio 247 can happen. --> 248 <!-- Just viewbox. Has intrinsic aspect ratio, but no width/height --> 249 <div class="container"> 250 <img class="target" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' style='fill:rgb(0,255,0);'/%3E%3C/svg%3E" style="" 251 data-expected-width="338" data-expected-height="182" data-offset-y="11" data-offset-x="59" 252 > 253 </div> 254 <!-- Just viewbox. Has aspect_ratio, but no intrinsic size 255 inline_width defaults to container width --> 256 <div class="container"> 257 <img class="target" src="data:image/svg+xml,%3Csvg viewBox='0 0 100 10' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' style='fill:rgb(0,255,0);'/%3E%3C/svg%3E" 258 data-expected-width="388" data-expected-height="67" data-offset-y="126" data-offset-x="9" 259 > 260 </div> 261 <!-- Just viewbox. Has aspect_ratio, but no intrinsic size 262 inline_width is constrained by left/right, height computed proportionally --> 263 <div class="container"> 264 <img class="target" style="left:100px;right:100px;" src="data:image/svg+xml,%3Csvg viewBox='0 0 100 10' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' style='fill:rgb(0,255,0);'/%3E%3C/svg%3E" 265 data-expected-width="188" data-expected-height="47" data-offset-y="146" data-offset-x="109" 266 > 267 </div> 268 <!-- Same as previous test, but with max-width:fit-content. crbug.com/1010798 269 --> 270 <div class="container"> 271 <img class="target" style="left:100px;right:100px;max-width:fit-content" src="data:image/svg+xml,%3Csvg viewBox='0 0 100 10' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' style='fill:rgb(0,255,0);'/%3E%3C/svg%3E" 272 data-expected-width="188" data-expected-height="47" data-offset-y="146" data-offset-x="109" 273 > 274 </div> 275 <!-- Viewbox + svg width. Has aspect_ratio and width. Height is scaled --> 276 <div class="container"> 277 <img class="target" src="data:image/svg+xml,%3Csvg viewBox='0 0 100 10' width='100px' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' style='fill:rgb(0,255,0);'/%3E%3C/svg%3E" 278 data-expected-width="138" data-expected-height="42" data-offset-y="151" data-offset-x="259" 279 > 280 </div> 281 <!-- Viewbox + svg height. Has aspect_ratio and height. Width is scaled --> 282 <div class="container"> 283 <img class="target" src="data:image/svg+xml,%3Csvg viewBox='0 0 100 10' height='20px' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' style='fill:rgb(0,255,0);'/%3E%3C/svg%3E" 284 data-expected-width="238" data-expected-height="52" data-offset-y="141" data-offset-x="159" 285 > 286 </div> 287 <!-- Viewbox + css height. Has aspect_ratio and height. Width is scaled --> 288 <div class="container"> 289 <img class="target" style="height:20px" src="data:image/svg+xml,%3Csvg viewBox='0 0 100 10' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' style='fill:rgb(0,255,0);'/%3E%3C/svg%3E" 290 data-expected-width="238" data-expected-height="52" data-offset-y="141" data-offset-x="159" 291 > 292 </div> 293 <!-- Viewbox + css width. Has aspect_ratio and width. Height is scaled --> 294 <div class="container"> 295 <img class="target" style="width:238px" src="data:image/svg+xml,%3Csvg viewBox='0 0 100 10' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' style='fill:rgb(0,255,0);'/%3E%3C/svg%3E" 296 data-expected-width="276" data-expected-height="56" data-offset-y="137" data-offset-x="121" 297 > 298 </div> 299 <script> 300 // initialize png images with 200x150 green png 301 let pngSrc="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAACWAQMAAAChElVaAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABlBMVEUAgAD///8UPy9PAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+MBDwkdA1Cz/EMAAAAbSURBVEjH7cGBAAAAAMOg+VPf4ARVAQAAAM8ADzwAAeM8wQsAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDEtMTVUMTc6Mjk6MDMtMDg6MDCYDy9IAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTAxLTE1VDE3OjI5OjAzLTA4OjAw6VKX9AAAAABJRU5ErkJggg==" 302 ; 303 let images = document.querySelectorAll("img.png"); 304 for (let i=0; i<images.length; ++i) { 305 images[i].src = pngSrc; 306 } 307 308 // SVG with no intrinsic width/height 309 let svgSrc="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' style='fill:rgb(0,255,0);'/%3E%3C/svg%3E "; 310 images = document.querySelectorAll("img.svg"); 311 for (let i=0; i<images.length; ++i) { 312 images[i].src = svgSrc; 313 } 314 315 function makeTest(el) { 316 return function() { 317 if (!el.getAttribute("data-expected-width")) { 318 // This code is used to generate reference data for the tests. 319 let text = `data-expected-width="${el.offsetWidth}" data-expected-height="${el.offsetHeight}" data-offset-y="${el.offsetTop}" data-offset-x="${el.offsetLeft}"`; 320 el.parentElement.innerText = text; 321 return; 322 } 323 assert_equals(el.offsetWidth + "", el.getAttribute("data-expected-width"), "incorrect offsetWidth"); 324 assert_equals(el.offsetHeight + "", el.getAttribute("data-expected-height"), "incorrect offsetHeight"); 325 assert_equals(el.offsetTop + "", el.getAttribute("data-offset-y"), "incorrect offsetTop"); 326 assert_equals(el.offsetLeft + "", el.getAttribute("data-offset-x"), "incorrect offsetLeft"); 327 } 328 }; 329 330 331 let testNameIndex = 1; 332 function getTestName(el) { 333 let svg = el.classList.contains("svg") ? " svg" : ""; 334 return "minmax replaced " + el.nodeName + svg + " " + testNameIndex++; 335 }; 336 337 function testAfterImageLoads(img, test) { 338 let asyncTest = async_test(getTestName(img)); 339 img.addEventListener("error", asyncTest.unreached_func("Load shouldn't fail")); 340 img.addEventListener("load", _ => { 341 asyncTest.step(test); 342 asyncTest.done(); 343 }); 344 }; 345 346 let testElements = document.querySelectorAll(".target"); 347 348 for (let i=0; i<testElements.length; ++i) { 349 let myTest = makeTest(testElements[i]); 350 if (testElements[i].nodeName == "IMG" && !testElements[i].complete) { 351 testAfterImageLoads(testElements[i], myTest); 352 } else { 353 test(myTest, getTestName(testElements[i])); 354 } 355 } 356 </script>