anchor-name-mutation.html (7611B)
1 <!DOCTYPE html> 2 3 <html> 4 5 <title>Tests that when an anchor name is mutated, the anchor-positioned element adjusts to the new anchor</title> 6 7 <link rel="author" href="mailto:kiet.ho@apple.com"> 8 <link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#name"> 9 10 <script src="/resources/testharness.js"></script> 11 <script src="/resources/testharnessreport.js"></script> 12 <script src="/common/rendering-utils.js"></script> 13 14 <style> 15 .containing-block { 16 position: relative; 17 width: 300px; 18 height: 300px; 19 20 border: 1px black solid; 21 } 22 23 .cell { 24 width: 100px; 25 height: 100px; 26 } 27 28 #anchor-1 { 29 position: absolute; 30 top: 0; 31 left: 0; 32 33 background: green; 34 } 35 36 #anchor-2 { 37 position: absolute; 38 top: 100px; 39 left: 0; 40 41 background: blue; 42 } 43 44 .anchor { 45 anchor-name: --anchor; 46 } 47 48 #anchor-positioned { 49 background: orange; 50 51 position: absolute; 52 top: 0; 53 left: 0; 54 } 55 56 .positioned-using-anchor-function-explicit-name { 57 position: absolute; 58 top: anchor(--anchor bottom) !important; 59 left: anchor(--anchor right) !important; 60 } 61 62 .positioned-using-anchor-function-implicit-name { 63 position: absolute; 64 position-anchor: --anchor; 65 66 top: anchor(bottom) !important; 67 left: anchor(right) !important; 68 } 69 70 .positioned-using-position-area { 71 position: absolute; 72 position-anchor: --anchor; 73 74 position-area: bottom right; 75 } 76 </style> 77 78 <body> 79 <main id="main"> 80 </main> 81 82 <template id="test-template"> 83 <div class="containing-block"> 84 <div class="cell" id="anchor-1"></div> 85 <div class="cell" id="anchor-2"></div> 86 <div class="cell" id="anchor-positioned"></div> 87 </div> 88 </template> 89 90 <script> 91 function inflate(t, template_element) { 92 const main_element = document.getElementById("main"); 93 94 t.add_cleanup(() => main_element.replaceChildren()); 95 main_element.append(template_element.content.cloneNode(true)); 96 } 97 98 const test_template = document.getElementById("test-template"); 99 100 const positioning_methods = [ 101 "positioned-using-anchor-function-explicit-name", 102 "positioned-using-anchor-function-implicit-name", 103 "positioned-using-position-area" 104 ] 105 106 for (let positioning_method of positioning_methods) { 107 promise_test(async (t) => { 108 inflate(t, test_template); 109 110 const anchor1 = document.getElementById("anchor-1"); 111 const anchorPositioned = document.getElementById("anchor-positioned"); 112 113 anchorPositioned.classList.add(positioning_method); 114 115 // Here, anchorPositioned should be at the default location (top-left of containing block) 116 // This is because the anchor elements don't have an anchor name yet. 117 assert_equals(anchorPositioned.offsetTop, 0); 118 assert_equals(anchorPositioned.offsetLeft, 0); 119 120 anchor1.classList.add("anchor"); 121 122 // Here, anchorPositioned should be bottom-right of anchor1 123 assert_equals(anchorPositioned.offsetTop, 100); 124 assert_equals(anchorPositioned.offsetLeft, 100); 125 }, `Tests when an anchor-name is added later ${positioning_method}`); 126 127 promise_test(async (t) => { 128 inflate(t, test_template); 129 130 const anchor1 = document.getElementById("anchor-1"); 131 const anchorPositioned = document.getElementById("anchor-positioned"); 132 133 anchor1.classList.add("anchor"); 134 anchorPositioned.classList.add(positioning_method); 135 136 // Here, anchorPositioned should be bottom-right of anchor1 137 assert_equals(anchorPositioned.offsetTop, 100); 138 assert_equals(anchorPositioned.offsetLeft, 100); 139 140 anchor1.classList.remove("anchor"); 141 142 // Here, anchorPositioned should be at the default location (top-left of containing block) 143 // This is because the anchor elements don't have an anchor name. 144 assert_equals(anchorPositioned.offsetTop, 0); 145 assert_equals(anchorPositioned.offsetLeft, 0); 146 }, `Tests when an anchor-name is removed later ${positioning_method}`); 147 148 promise_test(async (t) => { 149 inflate(t, test_template); 150 151 const anchor1 = document.getElementById("anchor-1"); 152 const anchor2 = document.getElementById("anchor-2"); 153 const anchorPositioned = document.getElementById("anchor-positioned"); 154 155 anchor1.classList.add("anchor"); 156 anchorPositioned.classList.add(positioning_method); 157 158 // Here, anchorPositioned should be bottom-right of anchor1 159 assert_equals(anchorPositioned.offsetTop, 100); 160 assert_equals(anchorPositioned.offsetLeft, 100); 161 162 anchor1.classList.remove("anchor"); 163 anchor2.classList.add("anchor"); 164 165 // Here, anchorPositioned should be bottom-right of anchor2 166 assert_equals(anchorPositioned.offsetTop, 200); 167 assert_equals(anchorPositioned.offsetLeft, 100); 168 }, `Tests when an anchor-name moves from one element to another ${positioning_method}`); 169 170 promise_test(async (t) => { 171 inflate(t, test_template); 172 173 const anchor1 = document.getElementById("anchor-1"); 174 const anchor2 = document.getElementById("anchor-2"); 175 const anchorPositioned = document.getElementById("anchor-positioned"); 176 177 anchor1.classList.add("anchor"); 178 anchorPositioned.classList.add(positioning_method); 179 180 // Here, anchorPositioned should be bottom-right of anchor1 181 assert_equals(anchorPositioned.offsetTop, 100); 182 assert_equals(anchorPositioned.offsetLeft, 100); 183 184 anchor2.classList.add("anchor"); 185 186 // Here, anchorPositioned should be bottom-right of anchor2 187 assert_equals(anchorPositioned.offsetTop, 200); 188 assert_equals(anchorPositioned.offsetLeft, 100); 189 }, `Tests when a new anchor candidate is added (which wins out previous anchor) ${positioning_method}`); 190 191 192 promise_test(async (t) => { 193 inflate(t, test_template); 194 195 const anchor1 = document.getElementById("anchor-1"); 196 const anchor2 = document.getElementById("anchor-2"); 197 const anchorPositioned = document.getElementById("anchor-positioned"); 198 199 anchor2.classList.add("anchor"); 200 anchorPositioned.classList.add(positioning_method); 201 202 // Here, anchorPositioned should be bottom-right of anchor2 203 assert_equals(anchorPositioned.offsetTop, 200); 204 assert_equals(anchorPositioned.offsetLeft, 100); 205 206 anchor1.classList.add("anchor"); 207 208 // Here, anchorPositioned should be bottom-right of anchor2 209 assert_equals(anchorPositioned.offsetTop, 200); 210 assert_equals(anchorPositioned.offsetLeft, 100); 211 }, `Tests when a new anchor candidate is added (which loses out previous anchor) ${positioning_method}`); 212 } 213 </script> 214 215 </body> 216 217 </html>