margin-collapse-through-for-various-height-values.tentative.html (6680B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <link rel="author" title="Oriol Brufau" href="obrufau@igalia.com"> 4 <link rel="help" href="https://www.w3.org/TR/CSS22/box.html#collapsing-margins"> 5 <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/8919"> 6 <link rel="help" href="https://github.com/servo/servo/pull/32064"> 7 <meta name="assert" content=" 8 Margins can collapse through when the used height is zero, regardless of the computed values 9 of `height`, `min-height` and `max-height`. 10 11 Note that this test uses sizing values which didn't exist in CSS2, but since the expectations 12 only depend on the used height, the test can still pass on implementations that don't support 13 these values. 14 "> 15 16 <style> 17 .before, .after { 18 overflow: hidden; 19 } 20 .wrapper { 21 border: 1px solid; 22 margin-bottom: 2em; 23 } 24 .test { 25 margin: 50px; 26 } 27 </style> 28 29 <div id="log"></div> 30 31 <script src="/resources/testharness.js"></script> 32 <script src="/resources/testharnessreport.js"></script> 33 <script> 34 let testcases = [ 35 // Tests for `height` 36 { height: "auto" }, 37 { height: "0px" }, 38 { height: "1px" }, 39 { height: "0%", parentHeight: "auto" }, 40 { height: "0%", parentHeight: "0px" }, 41 { height: "0%", parentHeight: "100px" }, 42 { height: "1%", parentHeight: "auto" }, 43 { height: "1%", parentHeight: "0px" }, 44 { height: "1%", parentHeight: "100px" }, 45 { height: "calc(0px + 0%)", parentHeight: "auto" }, 46 { height: "calc(0px + 0%)", parentHeight: "0px" }, 47 { height: "calc(0px + 0%)", parentHeight: "100px" }, 48 { height: "calc(0px + 1%)", parentHeight: "auto" }, 49 { height: "calc(0px + 1%)", parentHeight: "0px" }, 50 { height: "calc(0px + 1%)", parentHeight: "100px" }, 51 { height: "calc(1px + 0%)", parentHeight: "auto" }, 52 { height: "calc(1px + 0%)", parentHeight: "0px" }, 53 { height: "calc(1px + 0%)", parentHeight: "100px" }, 54 { height: "calc(1px + 1%)", parentHeight: "auto" }, 55 { height: "calc(1px + 1%)", parentHeight: "0px" }, 56 { height: "calc(1px + 1%)", parentHeight: "100px" }, 57 { height: "stretch", parentHeight: "auto" }, 58 { height: "stretch", parentHeight: "0px" }, 59 { height: "stretch", parentHeight: "100px" }, 60 61 // Tests for `min-height` (with `height: auto`) 62 { minHeight: "auto" }, 63 { minHeight: "0px" }, 64 { minHeight: "1px" }, 65 { minHeight: "0%", parentHeight: "auto" }, 66 { minHeight: "0%", parentHeight: "0px" }, 67 { minHeight: "0%", parentHeight: "100px" }, 68 { minHeight: "1%", parentHeight: "auto" }, 69 { minHeight: "1%", parentHeight: "0px" }, 70 { minHeight: "1%", parentHeight: "100px" }, 71 { minHeight: "calc(0px + 0%)", parentHeight: "auto" }, 72 { minHeight: "calc(0px + 0%)", parentHeight: "0px" }, 73 { minHeight: "calc(0px + 0%)", parentHeight: "100px" }, 74 { minHeight: "calc(0px + 1%)", parentHeight: "auto" }, 75 { minHeight: "calc(0px + 1%)", parentHeight: "0px" }, 76 { minHeight: "calc(0px + 1%)", parentHeight: "100px" }, 77 { minHeight: "calc(1px + 0%)", parentHeight: "auto" }, 78 { minHeight: "calc(1px + 0%)", parentHeight: "0px" }, 79 { minHeight: "calc(1px + 0%)", parentHeight: "100px" }, 80 { minHeight: "calc(1px + 1%)", parentHeight: "auto" }, 81 { minHeight: "calc(1px + 1%)", parentHeight: "0px" }, 82 { minHeight: "calc(1px + 1%)", parentHeight: "100px" }, 83 { minHeight: "stretch", parentHeight: "auto" }, 84 { minHeight: "stretch", parentHeight: "0px" }, 85 { minHeight: "stretch", parentHeight: "100px" }, 86 87 // Tests for `max-height` (with `height: 1px`) 88 { height: "1px", maxHeight: "none" }, 89 { height: "1px", maxHeight: "0px" }, 90 { height: "1px", maxHeight: "1px" }, 91 { height: "1px", maxHeight: "0%", parentHeight: "auto" }, 92 { height: "1px", maxHeight: "0%", parentHeight: "0px" }, 93 { height: "1px", maxHeight: "0%", parentHeight: "100px" }, 94 { height: "1px", maxHeight: "1%", parentHeight: "auto" }, 95 { height: "1px", maxHeight: "1%", parentHeight: "0px" }, 96 { height: "1px", maxHeight: "1%", parentHeight: "100px" }, 97 { height: "1px", maxHeight: "calc(0px + 0%)", parentHeight: "auto" }, 98 { height: "1px", maxHeight: "calc(0px + 0%)", parentHeight: "0px" }, 99 { height: "1px", maxHeight: "calc(0px + 0%)", parentHeight: "100px" }, 100 { height: "1px", maxHeight: "calc(0px + 1%)", parentHeight: "auto" }, 101 { height: "1px", maxHeight: "calc(0px + 1%)", parentHeight: "0px" }, 102 { height: "1px", maxHeight: "calc(0px + 1%)", parentHeight: "100px" }, 103 { height: "1px", maxHeight: "calc(1px + 0%)", parentHeight: "auto" }, 104 { height: "1px", maxHeight: "calc(1px + 0%)", parentHeight: "0px" }, 105 { height: "1px", maxHeight: "calc(1px + 0%)", parentHeight: "100px" }, 106 { height: "1px", maxHeight: "calc(1px + 1%)", parentHeight: "auto" }, 107 { height: "1px", maxHeight: "calc(1px + 1%)", parentHeight: "0px" }, 108 { height: "1px", maxHeight: "calc(1px + 1%)", parentHeight: "100px" }, 109 { height: "1px", maxHeight: "stretch", parentHeight: "auto" }, 110 { height: "1px", maxHeight: "stretch", parentHeight: "0px" }, 111 { height: "1px", maxHeight: "stretch", parentHeight: "100px" }, 112 ]; 113 114 function generate(testcase, serialization) { 115 let { height, minHeight, maxHeight, parentHeight, ...unrecognized } = testcase; 116 assert_array_equals(Object.keys(unrecognized), [], "No unrecognized key."); 117 let wrapper = document.createElement("div"); 118 wrapper.className = "wrapper"; 119 wrapper.style.height = parentHeight || ""; 120 let before = document.createElement("div"); 121 before.className = "before"; 122 before.textContent = serialization; 123 let after = document.createElement("div"); 124 after.className = "after"; 125 let test = document.createElement("div"); 126 test.className = "test"; 127 test.style.height = height || ""; 128 test.style.minHeight = minHeight || ""; 129 test.style.maxHeight = maxHeight || ""; 130 wrapper.append(before, test, after); 131 document.body.append(wrapper); 132 return [before, test, after]; 133 } 134 function round(value) { 135 return Math.round(value * 10) / 10; 136 } 137 138 let resolveDomReady; 139 let domReady = new Promise(resolve => { 140 resolveDomReady = resolve; 141 }); 142 for (let testcase of testcases) { 143 let serialization = JSON.stringify(testcase); 144 promise_test(async () => { 145 let [before, test, after] = generate(testcase, serialization); 146 147 // The checks below force layout, so as an optimization, run them asynchronously after generating all tests. 148 await domReady; 149 let height = round(test.getBoundingClientRect().height); 150 let marginSum = round(after.getBoundingClientRect().top - before.getBoundingClientRect().bottom) - height; 151 if (height === 0) { 152 assert_equals(marginSum, 50, "margins should collapse through"); 153 } else { 154 assert_equals(marginSum, 100, "margins should NOT collapse through when height is " + height); 155 } 156 }, serialization); 157 } 158 resolveDomReady(); 159 </script>