anchor-scope-display-contents.tentative.html (8869B)
1 <!DOCTYPE html> 2 <title>CSS Anchor Positioning: Basic anchor-scope behavior when scope element has display:contents property</title> 3 <link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#anchor-scope"> 4 <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/12783"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <!-- This test is based on anchor-scope-basic.html --> 8 <style> 9 .scope-all { anchor-scope: all; display: contents; } 10 .scope-a { anchor-scope: --a; display: contents; } 11 .scope-b { anchor-scope: --b; ; display: contents; } 12 .scope-ab { anchor-scope: --a, --b; ; display: contents; } 13 14 .anchor-a { anchor-name: --a; } 15 .anchor-b { anchor-name: --b; } 16 .anchor-ab { anchor-name: --a, --b; } 17 .anchor-a, .anchor-b, .anchor-ab { 18 background: skyblue; 19 height: 10px; 20 } 21 22 .anchored-a { position-anchor: --a; } 23 .anchored-b { position-anchor: --b; } 24 .anchored-a, .anchored-b { 25 position: absolute; 26 top: anchor(bottom); 27 left: anchor(left); 28 width: 5px; 29 height: 5px; 30 background: coral; 31 } 32 33 /* Containing block */ 34 main { 35 position: relative; 36 width: 100px; 37 height: 100px; 38 border: 1px solid black; 39 } 40 </style> 41 <script> 42 function inflate(t, template_element) { 43 t.add_cleanup(() => main.replaceChildren()); 44 main.append(template_element.content.cloneNode(true)); 45 } 46 </script> 47 48 <main id=main> 49 </main> 50 51 <template id=test_inclusive_subtree> 52 <div class="scope-a anchor-a"> <!--A--> 53 <div class=anchored-a></div> 54 </div> 55 </template> 56 <script> 57 test((t) => { 58 inflate(t, test_inclusive_subtree); 59 // In this case, anchor scope with display:contents is ignored. 60 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '0px'); 61 }, 'Can anchor to a name both defined and scoped by the same element'); 62 </script> 63 64 <template id=test_skips_named_anchor_with_scope> 65 <div class="anchor-a"></div> 66 <div class="anchor-a"></div> 67 <div class="anchor-a"></div> <!--A--> 68 <div class="scope-a anchor-a"></div> 69 <div class=anchored-a></div> 70 </template> 71 <script> 72 test((t) => { 73 inflate(t, test_skips_named_anchor_with_scope); 74 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '30px'); 75 }, 'Sibling can not anchor into anchor-scope, even when anchor-name present'); 76 </script> 77 78 <template id=test_scope_all_common_ancestor> 79 <div class=scope-all> 80 <div class=anchor-a></div> 81 <div class=anchor-a></div> 82 <div class=anchor-a></div> 83 <div class=anchor-a></div><!--A--> 84 <div class=anchored-a></div> 85 </div> 86 </template> 87 <script> 88 test((t) => { 89 inflate(t, test_scope_all_common_ancestor); 90 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '40px'); 91 }, 'anchor-scope:all on common ancestor'); 92 </script> 93 94 <template id=test_scope_named_common_ancestor> 95 <div class=scope-a> 96 <div class=anchor-a></div> 97 <div class=anchor-a></div> 98 <div class=anchor-a></div> 99 <div class=anchor-a></div><!--A--> 100 <div class=anchored-a></div> 101 </div> 102 </template> 103 <script> 104 test((t) => { 105 inflate(t, test_scope_named_common_ancestor); 106 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '40px'); 107 }, 'anchor-scope:--a on common ancestor'); 108 </script> 109 110 <template id=test_scope_all_sibling> 111 <div class=anchor-a></div> 112 <div class=anchor-a></div><!--A--> 113 <div class=scope-all> 114 <div class=anchor-a></div> 115 <div class=anchor-a></div> 116 </div> 117 <div class=anchored-a></div> 118 </template> 119 <script> 120 test((t) => { 121 inflate(t, test_scope_all_sibling); 122 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '20px'); 123 }, 'anchor-scope:all on sibling'); 124 </script> 125 126 <template id=test_scope_all_multiple> 127 <div class=anchor-b></div><!--B--> 128 <div class=anchor-a></div><!--A--> 129 <div class=scope-all> 130 <div class=anchor-b></div> 131 <div class=anchor-a></div> 132 </div> 133 <div class=anchored-a></div> 134 <div class=anchored-b></div> 135 </template> 136 <script> 137 test((t) => { 138 inflate(t, test_scope_all_multiple); 139 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '20px'); 140 assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '10px'); 141 }, 'anchor-scope:all scopes multiple names'); 142 </script> 143 144 <template id=test_scope_ab> 145 <div class=anchor-b></div><!--B--> 146 <div class=anchor-a></div><!--A--> 147 <div class=scope-ab> 148 <div class=anchor-b></div> 149 <div class=anchor-a></div> 150 </div> 151 <div class=anchored-a></div> 152 <div class=anchored-b></div> 153 </template> 154 <script> 155 test((t) => { 156 inflate(t, test_scope_ab); 157 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '20px'); 158 assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '10px'); 159 }, 'anchor-scope:--a,--b scopes --a and --b'); 160 </script> 161 162 <template id=test_scope_a> 163 <div class=anchor-b></div> 164 <div class=anchor-a></div><!--A--> 165 <div class=scope-a> 166 <div class=anchor-b></div> 167 <div class=anchor-ab></div><!--B--> 168 <div class=anchor-a></div> 169 </div> 170 <div class=anchored-a></div> 171 <div class=anchored-b></div> 172 </template> 173 <script> 174 test((t) => { 175 inflate(t, test_scope_a); 176 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '20px'); 177 assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '40px'); 178 }, 'anchor-scope:--a scopes only --a'); 179 </script> 180 181 <template id=test_scope_b> 182 <div class=anchor-b></div><!--B--> 183 <div class=anchor-a></div> 184 <div class=scope-b> 185 <div class=anchor-a></div><!--A--> 186 <div class=anchor-b></div> 187 </div> 188 <div class=anchored-a></div> 189 <div class=anchored-b></div> 190 </template> 191 <script> 192 test((t) => { 193 inflate(t, test_scope_b); 194 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '30px'); 195 assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '10px'); 196 }, 'anchor-scope:--b scopes only --b'); 197 </script> 198 199 <template id=test_out_of_flow_anchors> 200 <style> 201 .anchor-a, .anchor-b { 202 position: absolute; 203 width: 5px; 204 height: 5px; 205 } 206 </style> 207 <div class=anchor-b style='left:10px'></div> 208 <div class=anchor-a style='left:20px'></div><!--A--> 209 <div class=scope-a> 210 <div class=anchor-b style='left:30px'></div><!--B--> 211 <div class=anchor-a style='left:40px'></div> 212 </div> 213 <div class=anchored-a></div> 214 <div class=anchored-b></div> 215 </template> 216 <script> 217 test((t) => { 218 inflate(t, test_out_of_flow_anchors); 219 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '5px'); 220 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).left, '20px'); 221 222 assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '5px'); 223 assert_equals(getComputedStyle(main.querySelector('.anchored-b')).left, '30px'); 224 }, 'anchor-scope:--a scopes only --a (out-of-flow anchors)'); 225 </script> 226 227 <!-- Out-of-flow anchor within anchor-scope:--a --> 228 <template id=test_mixed_flow_anchors> 229 <style> 230 .abs { 231 position: absolute; 232 width: 5px; 233 height: 5px; 234 } 235 </style> 236 <div class=anchor-b></div> 237 <div class=anchor-a></div><!--A--> 238 <div class=scope-a> 239 <div class=anchor-b></div><!--B--> 240 <div class='anchor-a abs' style='top:50px'></div> 241 </div> 242 <div class=anchored-a></div> 243 <div class=anchored-b></div> 244 </template> 245 <script> 246 test((t) => { 247 inflate(t, test_mixed_flow_anchors); 248 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '20px'); 249 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).left, '0px'); 250 251 assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '30px'); 252 assert_equals(getComputedStyle(main.querySelector('.anchored-b')).left, '0px'); 253 }, 'anchor-scope:--a scopes only --a (both out-of-flow and in-flow anchors)'); 254 </script> 255 256 <!-- In-flow anchor within anchor-scope:--a --> 257 <template id=test_mixed_flow_anchors_reverse> 258 <style> 259 .abs { 260 position: absolute; 261 width: 5px; 262 height: 5px; 263 } 264 </style> 265 <div class=anchor-b></div> 266 <div class='anchor-a abs' style='top:50px'></div><!--A--> 267 <div class=scope-a> 268 <div class=anchor-b></div><!--B--> 269 <div class=anchor-a></div> 270 </div> 271 <div class=anchored-a></div> 272 <div class=anchored-b></div> 273 </template> 274 <script> 275 test((t) => { 276 inflate(t, test_mixed_flow_anchors_reverse); 277 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '55px'); 278 assert_equals(getComputedStyle(main.querySelector('.anchored-a')).left, '0px'); 279 280 assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '20px'); 281 assert_equals(getComputedStyle(main.querySelector('.anchored-b')).left, '0px'); 282 }, 'anchor-scope:--a scopes only --a (both out-of-flow and in-flow anchors, reverse)'); 283 </script>