container-for-shadow-dom.html (13106B)
1 <!doctype html> 2 <meta charset="utf-8"> 3 <title>CSS Container Queries Test: query container for Shadow DOM</title> 4 <link rel="help" href="https://drafts.csswg.org/css-conditional-5/#query-container"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="support/cq-testcommon.js"></script> 8 <style> 9 #ancestor-across-root, 10 #ancestor-skip-slotting, 11 #ancestor-slotted, 12 #ancestor-host, 13 #ancestor-part, 14 #ancestor-slotted-before, 15 #ancestor-host-before, 16 #ancestor-part-before, 17 #ancestor-inner-part, 18 #ancestor-slot-fallback, 19 #inner-scope-host-part { 20 width: 400px; 21 container-type: inline-size; 22 } 23 </style> 24 25 <div id="ancestor-across-root"> 26 <div> 27 <template shadowrootmode="open"> 28 <style> 29 @container (width = 400px) { 30 #t1 { color: green; } 31 } 32 </style> 33 <div id="t1"></div> 34 </template> 35 </div> 36 </div> 37 38 <div id="ancestor-skip-slotting"> 39 <div> 40 <template shadowrootmode="open"> 41 <style> 42 div { 43 width: 200px; 44 container-type: inline-size; 45 } 46 </style> 47 <div> 48 <slot></slot> 49 </div> 50 </template> 51 <style> 52 @container (width = 200px) { 53 #t2 { color: green; } 54 } 55 </style> 56 <div id="t2"></div> 57 </div> 58 </div> 59 60 <div id="ancestor-slotted"> 61 <div> 62 <template shadowrootmode="open"> 63 <style> 64 slot { 65 display: block; 66 width: 200px; 67 container-type: inline-size; 68 } 69 @container (width = 200px) { 70 ::slotted(#t3) { color: green; } 71 } 72 </style> 73 <slot></slot> 74 </template> 75 <div id="t3"></div> 76 </div> 77 </div> 78 79 <div id="ancestor-host"> 80 <div id="t4"> 81 <template shadowrootmode="open"> 82 <style> 83 @container (width = 400px) { 84 :host(#t4) { color: green; } 85 } 86 </style> 87 </template> 88 </div> 89 </div> 90 91 <div id="ancestor-part"> 92 <div> 93 <template shadowrootmode="open"> 94 <style> 95 div { 96 width: 200px; 97 container-type: inline-size; 98 } 99 </style> 100 <div> 101 <span id="t5" part="part"></span> 102 </div> 103 </template> 104 <style> 105 @container (width = 200px) { 106 #ancestor-part > div::part(part) { color: green; } 107 } 108 </style> 109 </div> 110 </div> 111 112 <div id="ancestor-slotted-before"> 113 <div> 114 <template shadowrootmode="open"> 115 <style> 116 slot { 117 display: block; 118 width: 200px; 119 container-type: inline-size; 120 } 121 @container (width = 400px) { 122 ::slotted(#t6)::before { 123 content: "X"; 124 color: green; 125 } 126 } 127 </style> 128 <slot></slot> 129 </template> 130 <style> 131 #t6 { 132 width: 400px; 133 container-type: inline-size; 134 } 135 </style> 136 <div id="t6"></div> 137 </div> 138 </div> 139 140 <div id="ancestor-host-before"> 141 <div id="t7"> 142 <template shadowrootmode="open"> 143 <style> 144 :host { 145 width: 200px; 146 container-type: inline-size; 147 } 148 @container (width = 200px) { 149 :host(#t7)::before { 150 content: "X"; 151 color: green; 152 } 153 } 154 </style> 155 </template> 156 </div> 157 </div> 158 159 <div id="ancestor-part-before"> 160 <style> 161 @container (width = 200px) { 162 #ancestor-part-before > div::part(part)::before { 163 content: "X"; 164 color: green; 165 } 166 } 167 </style> 168 <div> 169 <template shadowrootmode="open"> 170 <style> 171 div { 172 width: 200px; 173 container-type: inline-size; 174 } 175 </style> 176 <div> 177 <span id="t8" part="part"></span> 178 </div> 179 </template> 180 </div> 181 </div> 182 183 <div id="ancestor-inner-part"> 184 <style> 185 @container (width = 200px) { 186 #ancestor-inner-part > div::part(inner-part) { color: green; } 187 } 188 </style> 189 <div> 190 <template shadowrootmode="open"> 191 <style> 192 div { 193 width: 200px; 194 container-type: inline-size; 195 } 196 </style> 197 <div exportparts="inner-part"> 198 <template shadowrootmode="open"> 199 <style> 200 div { 201 width: 200px; 202 container-type: inline-size; 203 } 204 </style> 205 <div> 206 <span id="t9" part="inner-part"></span> 207 </div> 208 </template> 209 </div> 210 </template> 211 </div> 212 </div> 213 214 <div id="ancestor-slot-fallback"> 215 <div><template shadowrootmode="open"> 216 <style> 217 div { 218 width: 200px; 219 container-type: inline-size; 220 } 221 @container (width = 200px) { 222 #t10 { color: green; } 223 } 224 </style> 225 <div> 226 <slot><span id="t10"></span></slot> 227 </div> 228 </template></div> 229 </div> 230 231 <div id="container-for-part"> 232 <div> 233 <template shadowrootmode="open"> 234 <style> 235 div { 236 width: 200px; 237 container-type: inline-size; 238 } 239 #t11 { color: red; } 240 </style> 241 <div> 242 <span id="t11" part="part"></span> 243 </div> 244 </template> 245 <style> 246 @container (width = 200px) { 247 #container-for-part > div::part(part) { color: green; } 248 } 249 </style> 250 </div> 251 </div> 252 253 <div id="inner-scope-host-part"> 254 <div> 255 <template shadowrootmode="open"> 256 <style> 257 div { 258 width: 200px; 259 container-type: inline-size; 260 } 261 @container (width = 200px) { 262 :host::part(part) { color: green; } 263 } 264 </style> 265 <div> 266 <span id="t12" part="part"></span> 267 </div> 268 </template> 269 </div> 270 </div> 271 272 <div id="named-part-host"> 273 <template shadowrootmode="open"> 274 <style> 275 @container --part2 (width >= 0px) { 276 #named-part2-child { color: green; } 277 } 278 #named-part1 { 279 container: --part1 / inline-size; 280 color: red; 281 } 282 </style> 283 <div id="named-part1" part="part1"> 284 <div id="named-part1-child" part="part1-child"></div> 285 </div> 286 <div part="part2"> 287 <div id="named-part2-child" part="part2-child"></div> 288 </div> 289 </template> 290 <style> 291 #named-part-host::part(part2) { container: --part2 / inline-size; } 292 @container --part1 (width >= 0px) { 293 #named-part-host::part(part1-child) { color: green; } 294 } 295 </style> 296 </div> 297 298 <div id="named-slotted-host"> 299 <template shadowrootmode="open"> 300 <style> 301 @container --slot-container (width >= 0px) { 302 ::slotted(#slotted1) { color: green; } 303 } 304 #named-slotted-container { 305 container: --slot-container / inline-size; 306 } 307 </style> 308 <div id="named-slotted-container"> 309 <slot></slot> 310 </div> 311 </template> 312 <div id="slotted1"></div> 313 <div id="slotted2"></div> 314 <style> 315 @container --slot-container (width >= 0px) { 316 #slotted2 { color: green; } 317 } 318 </style> 319 </div> 320 321 <div id="named-host"> 322 <template shadowrootmode="open"> 323 <style> 324 :host { 325 container: --host-container / inline-size; 326 } 327 @container --host-container (width >= 0px) { 328 #host-descendant { color: green; } 329 ::slotted(#host-slotted1) { color: green; } 330 } 331 </style> 332 <div id="host-descendant"></div> 333 <slot></slot> 334 </template> 335 <div id="host-slotted1"></div> 336 <div id="host-slotted2"></div> 337 <style> 338 @container --host-container (width >= 0px) { 339 #host-slotted2 { color: green; } 340 } 341 </style> 342 </div> 343 344 <div> 345 <template shadowrootmode="open"> 346 <style> 347 .container { 348 width: 400px; 349 container-type: inline-size; 350 } 351 </style> 352 <div class="container"><slot></slot></div> 353 </template> 354 <style> 355 @container (width = 200px) { 356 #pseudo-1::before { color: green; } 357 } 358 @container (width = 400px) { 359 #pseudo-2::before { color: green; } 360 } 361 #pseudo-1 { 362 container-type: inline-size; 363 width: 200px; 364 } 365 </style> 366 <div id="pseudo-1"></div> 367 <div id="pseudo-2"></div> 368 </div> 369 370 <script> 371 setup(() => { 372 assert_implements_size_container_queries(); 373 }); 374 375 const green = "rgb(0, 128, 0)"; 376 const red = "rgb(255, 0, 0)"; 377 378 test(() => { 379 const t1 = document.querySelector("#ancestor-across-root > div").shadowRoot.querySelector("#t1"); 380 assert_equals(getComputedStyle(t1).color, green); 381 }, "Match container in outer tree"); 382 383 test(() => { 384 const t2 = document.querySelector("#t2"); 385 assert_equals(getComputedStyle(t2).color, green); 386 }, "Match container in walking flat tree ancestors"); 387 388 test(() => { 389 const t3 = document.querySelector("#t3"); 390 assert_equals(getComputedStyle(t3).color, green); 391 }, "Match container in ::slotted selector's originating element tree"); 392 393 test(() => { 394 const t4 = document.querySelector("#t4"); 395 assert_equals(getComputedStyle(t4).color, green); 396 }, "Match container in outer tree for :host"); 397 398 test(() => { 399 const t5 = document.querySelector("#ancestor-part > div").shadowRoot.querySelector("#t5"); 400 assert_equals(getComputedStyle(t5).color, green); 401 }, "Match container in ::part selector's originating element tree"); 402 403 test(() => { 404 const t6 = document.querySelector("#t6"); 405 assert_equals(getComputedStyle(t6, "::before").color, green); 406 }, "Match container for ::before in ::slotted selector's originating element tree"); 407 408 test(() => { 409 const t7 = document.querySelector("#t7"); 410 assert_equals(getComputedStyle(t7, "::before").color, green); 411 }, "Match container in outer tree for :host::before"); 412 413 test(() => { 414 const t8 = document.querySelector("#ancestor-part-before > div").shadowRoot.querySelector("#t8"); 415 assert_equals(getComputedStyle(t8, "::before").color, green); 416 }, "Match container for ::before in ::part selector's originating element tree"); 417 418 test(() => { 419 const outerhost = document.querySelector("#ancestor-inner-part > div"); 420 const innerhost = outerhost.shadowRoot.querySelector("div"); 421 const t9 = innerhost.shadowRoot.querySelector("#t9"); 422 assert_equals(getComputedStyle(t9).color, green); 423 }, "Match container for ::part selector's originating element tree for exportparts"); 424 425 test(() => { 426 const t10 = document.querySelector("#ancestor-slot-fallback > div").shadowRoot.querySelector("#t10"); 427 assert_equals(getComputedStyle(t10).color, green); 428 }, "Match container for slot light tree child fallback"); 429 430 test(() => { 431 const t11 = document.querySelector("#container-for-part > div").shadowRoot.querySelector("#t11"); 432 assert_equals(getComputedStyle(t11).color, green); 433 }, "Should match container inside shadow tree for ::part()"); 434 435 test(() => { 436 const t12 = document.querySelector("#inner-scope-host-part > div").shadowRoot.querySelector("#t12"); 437 assert_equals(getComputedStyle(t12).color, green); 438 }, "A :host::part rule should match containers in the originating element tree"); 439 440 test(() => { 441 const target = document.querySelector("#named-part-host").shadowRoot.querySelector("#named-part1-child"); 442 assert_equals(getComputedStyle(target).color, green); 443 }, "Container name set inside a shadow tree should match query using ::part on the outside"); 444 445 test(() => { 446 const target = document.querySelector("#named-part-host").shadowRoot.querySelector("#named-part2-child"); 447 assert_equals(getComputedStyle(target).color, green); 448 }, "Container name set with a ::part should match query inside the shadow tree"); 449 450 test(() => { 451 const target = document.querySelector("#slotted1"); 452 assert_equals(getComputedStyle(target).color, green); 453 }, "Container name set inside a shadow tree should match query for a ::slotted() rule inside the tree"); 454 455 test(() => { 456 const target = document.querySelector("#slotted2"); 457 assert_equals(getComputedStyle(target).color, green); 458 }, "Container name set inside a shadow tree should match query for host child on the outside"); 459 460 test(() => { 461 const target = document.querySelector("#named-host").shadowRoot.querySelector("#host-descendant"); 462 assert_equals(getComputedStyle(target).color, green); 463 }, "Container name set on :host from inside a shadow tree matching query inside the shadow tree"); 464 465 test(() => { 466 const target = document.querySelector("#host-slotted1"); 467 assert_equals(getComputedStyle(target).color, green); 468 }, "Container name set on :host from inside a shadow tree matching query for ::slotted inside the shadow tree"); 469 470 test(() => { 471 const target = document.querySelector("#host-slotted2"); 472 assert_equals(getComputedStyle(target).color, green); 473 }, "Container name set on :host from inside a shadow tree should match query for slotted from the outside of the shadow tree"); 474 475 test(() => { 476 const target = document.querySelector("#pseudo-1"); 477 assert_equals(getComputedStyle(target, "::before").color, green); 478 }, "The originating element should be the first container candidate of ::before"); 479 480 test(() => { 481 const target = document.querySelector("#pseudo-2"); 482 assert_equals(getComputedStyle(target, "::before").color, green); 483 }, "Search flat tree anchestors of the originating element of ::before"); 484 </script>