| <!doctype html> |
| <meta charset="utf-8"> |
| <title>CSS Container Queries Test: query container for Shadow DOM</title> |
| <link rel="help" href="https://drafts.csswg.org/css-conditional-5/#query-container"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="support/cq-testcommon.js"></script> |
| <style> |
| #ancestor-across-root, |
| #ancestor-skip-slotting, |
| #ancestor-slotted, |
| #ancestor-host, |
| #ancestor-part, |
| #ancestor-slotted-before, |
| #ancestor-host-before, |
| #ancestor-part-before, |
| #ancestor-inner-part, |
| #ancestor-slot-fallback, |
| #inner-scope-host-part { |
| width: 400px; |
| container-type: inline-size; |
| } |
| </style> |
| |
| <div id="ancestor-across-root"> |
| <div> |
| <template shadowrootmode="open"> |
| <style> |
| @container (width = 400px) { |
| #t1 { color: green; } |
| } |
| </style> |
| <div id="t1"></div> |
| </template> |
| </div> |
| </div> |
| |
| <div id="ancestor-skip-slotting"> |
| <div> |
| <template shadowrootmode="open"> |
| <style> |
| div { |
| width: 200px; |
| container-type: inline-size; |
| } |
| </style> |
| <div> |
| <slot></slot> |
| </div> |
| </template> |
| <style> |
| @container (width = 200px) { |
| #t2 { color: green; } |
| } |
| </style> |
| <div id="t2"></div> |
| </div> |
| </div> |
| |
| <div id="ancestor-slotted"> |
| <div> |
| <template shadowrootmode="open"> |
| <style> |
| slot { |
| display: block; |
| width: 200px; |
| container-type: inline-size; |
| } |
| @container (width = 200px) { |
| ::slotted(#t3) { color: green; } |
| } |
| </style> |
| <slot></slot> |
| </template> |
| <div id="t3"></div> |
| </div> |
| </div> |
| |
| <div id="ancestor-host"> |
| <div id="t4"> |
| <template shadowrootmode="open"> |
| <style> |
| @container (width = 400px) { |
| :host(#t4) { color: green; } |
| } |
| </style> |
| </template> |
| </div> |
| </div> |
| |
| <div id="ancestor-part"> |
| <div> |
| <template shadowrootmode="open"> |
| <style> |
| div { |
| width: 200px; |
| container-type: inline-size; |
| } |
| </style> |
| <div> |
| <span id="t5" part="part"></span> |
| </div> |
| </template> |
| <style> |
| @container (width = 200px) { |
| #ancestor-part > div::part(part) { color: green; } |
| } |
| </style> |
| </div> |
| </div> |
| |
| <div id="ancestor-slotted-before"> |
| <div> |
| <template shadowrootmode="open"> |
| <style> |
| slot { |
| display: block; |
| width: 200px; |
| container-type: inline-size; |
| } |
| @container (width = 400px) { |
| ::slotted(#t6)::before { |
| content: "X"; |
| color: green; |
| } |
| } |
| </style> |
| <slot></slot> |
| </template> |
| <style> |
| #t6 { |
| width: 400px; |
| container-type: inline-size; |
| } |
| </style> |
| <div id="t6"></div> |
| </div> |
| </div> |
| |
| <div id="ancestor-host-before"> |
| <div id="t7"> |
| <template shadowrootmode="open"> |
| <style> |
| :host { |
| width: 200px; |
| container-type: inline-size; |
| } |
| @container (width = 200px) { |
| :host(#t7)::before { |
| content: "X"; |
| color: green; |
| } |
| } |
| </style> |
| </template> |
| </div> |
| </div> |
| |
| <div id="ancestor-part-before"> |
| <style> |
| @container (width = 200px) { |
| #ancestor-part-before > div::part(part)::before { |
| content: "X"; |
| color: green; |
| } |
| } |
| </style> |
| <div> |
| <template shadowrootmode="open"> |
| <style> |
| div { |
| width: 200px; |
| container-type: inline-size; |
| } |
| </style> |
| <div> |
| <span id="t8" part="part"></span> |
| </div> |
| </template> |
| </div> |
| </div> |
| |
| <div id="ancestor-inner-part"> |
| <style> |
| @container (width = 200px) { |
| #ancestor-inner-part > div::part(inner-part) { color: green; } |
| } |
| </style> |
| <div> |
| <template shadowrootmode="open"> |
| <style> |
| div { |
| width: 200px; |
| container-type: inline-size; |
| } |
| </style> |
| <div exportparts="inner-part"> |
| <template shadowrootmode="open"> |
| <style> |
| div { |
| width: 200px; |
| container-type: inline-size; |
| } |
| </style> |
| <div> |
| <span id="t9" part="inner-part"></span> |
| </div> |
| </template> |
| </div> |
| </template> |
| </div> |
| </div> |
| |
| <div id="ancestor-slot-fallback"> |
| <div><template shadowrootmode="open"> |
| <style> |
| div { |
| width: 200px; |
| container-type: inline-size; |
| } |
| @container (width = 200px) { |
| #t10 { color: green; } |
| } |
| </style> |
| <div> |
| <slot><span id="t10"></span></slot> |
| </div> |
| </template></div> |
| </div> |
| |
| <div id="container-for-part"> |
| <div> |
| <template shadowrootmode="open"> |
| <style> |
| div { |
| width: 200px; |
| container-type: inline-size; |
| } |
| #t11 { color: red; } |
| </style> |
| <div> |
| <span id="t11" part="part"></span> |
| </div> |
| </template> |
| <style> |
| @container (width = 200px) { |
| #container-for-part > div::part(part) { color: green; } |
| } |
| </style> |
| </div> |
| </div> |
| |
| <div id="inner-scope-host-part"> |
| <div> |
| <template shadowrootmode="open"> |
| <style> |
| div { |
| width: 200px; |
| container-type: inline-size; |
| } |
| @container (width = 200px) { |
| :host::part(part) { color: green; } |
| } |
| </style> |
| <div> |
| <span id="t12" part="part"></span> |
| </div> |
| </template> |
| </div> |
| </div> |
| |
| <div id="named-part-host"> |
| <template shadowrootmode="open"> |
| <style> |
| @container --part2 (width >= 0px) { |
| #named-part2-child { color: green; } |
| } |
| #named-part1 { |
| container: --part1 / inline-size; |
| color: red; |
| } |
| </style> |
| <div id="named-part1" part="part1"> |
| <div id="named-part1-child" part="part1-child"></div> |
| </div> |
| <div part="part2"> |
| <div id="named-part2-child" part="part2-child"></div> |
| </div> |
| </template> |
| <style> |
| #named-part-host::part(part2) { container: --part2 / inline-size; } |
| @container --part1 (width >= 0px) { |
| #named-part-host::part(part1-child) { color: green; } |
| } |
| </style> |
| </div> |
| |
| <div id="named-slotted-host"> |
| <template shadowrootmode="open"> |
| <style> |
| @container --slot-container (width >= 0px) { |
| ::slotted(#slotted1) { color: green; } |
| } |
| #named-slotted-container { |
| container: --slot-container / inline-size; |
| } |
| </style> |
| <div id="named-slotted-container"> |
| <slot></slot> |
| </div> |
| </template> |
| <div id="slotted1"></div> |
| <div id="slotted2"></div> |
| <style> |
| @container --slot-container (width >= 0px) { |
| #slotted2 { color: green; } |
| } |
| </style> |
| </div> |
| |
| <div id="named-host"> |
| <template shadowrootmode="open"> |
| <style> |
| :host { |
| container: --host-container / inline-size; |
| } |
| @container --host-container (width >= 0px) { |
| #host-descendant { color: green; } |
| ::slotted(#host-slotted1) { color: green; } |
| } |
| </style> |
| <div id="host-descendant"></div> |
| <slot></slot> |
| </template> |
| <div id="host-slotted1"></div> |
| <div id="host-slotted2"></div> |
| <style> |
| @container --host-container (width >= 0px) { |
| #host-slotted2 { color: green; } |
| } |
| </style> |
| </div> |
| |
| <div> |
| <template shadowrootmode="open"> |
| <style> |
| .container { |
| width: 400px; |
| container-type: inline-size; |
| } |
| </style> |
| <div class="container"><slot></slot></div> |
| </template> |
| <style> |
| @container (width = 200px) { |
| #pseudo-1::before { color: green; } |
| } |
| @container (width = 400px) { |
| #pseudo-2::before { color: green; } |
| } |
| #pseudo-1 { |
| container-type: inline-size; |
| width: 200px; |
| } |
| </style> |
| <div id="pseudo-1"></div> |
| <div id="pseudo-2"></div> |
| </div> |
| |
| <script> |
| setup(() => { |
| assert_implements_size_container_queries(); |
| }); |
| |
| const green = "rgb(0, 128, 0)"; |
| const red = "rgb(255, 0, 0)"; |
| |
| test(() => { |
| const t1 = document.querySelector("#ancestor-across-root > div").shadowRoot.querySelector("#t1"); |
| assert_equals(getComputedStyle(t1).color, green); |
| }, "Match container in outer tree"); |
| |
| test(() => { |
| const t2 = document.querySelector("#t2"); |
| assert_equals(getComputedStyle(t2).color, green); |
| }, "Match container in walking flat tree ancestors"); |
| |
| test(() => { |
| const t3 = document.querySelector("#t3"); |
| assert_equals(getComputedStyle(t3).color, green); |
| }, "Match container in ::slotted selector's originating element tree"); |
| |
| test(() => { |
| const t4 = document.querySelector("#t4"); |
| assert_equals(getComputedStyle(t4).color, green); |
| }, "Match container in outer tree for :host"); |
| |
| test(() => { |
| const t5 = document.querySelector("#ancestor-part > div").shadowRoot.querySelector("#t5"); |
| assert_equals(getComputedStyle(t5).color, green); |
| }, "Match container in ::part selector's originating element tree"); |
| |
| test(() => { |
| const t6 = document.querySelector("#t6"); |
| assert_equals(getComputedStyle(t6, "::before").color, green); |
| }, "Match container for ::before in ::slotted selector's originating element tree"); |
| |
| test(() => { |
| const t7 = document.querySelector("#t7"); |
| assert_equals(getComputedStyle(t7, "::before").color, green); |
| }, "Match container in outer tree for :host::before"); |
| |
| test(() => { |
| const t8 = document.querySelector("#ancestor-part-before > div").shadowRoot.querySelector("#t8"); |
| assert_equals(getComputedStyle(t8, "::before").color, green); |
| }, "Match container for ::before in ::part selector's originating element tree"); |
| |
| test(() => { |
| const outerhost = document.querySelector("#ancestor-inner-part > div"); |
| const innerhost = outerhost.shadowRoot.querySelector("div"); |
| const t9 = innerhost.shadowRoot.querySelector("#t9"); |
| assert_equals(getComputedStyle(t9).color, green); |
| }, "Match container for ::part selector's originating element tree for exportparts"); |
| |
| test(() => { |
| const t10 = document.querySelector("#ancestor-slot-fallback > div").shadowRoot.querySelector("#t10"); |
| assert_equals(getComputedStyle(t10).color, green); |
| }, "Match container for slot light tree child fallback"); |
| |
| test(() => { |
| const t11 = document.querySelector("#container-for-part > div").shadowRoot.querySelector("#t11"); |
| assert_equals(getComputedStyle(t11).color, green); |
| }, "Should match container inside shadow tree for ::part()"); |
| |
| test(() => { |
| const t12 = document.querySelector("#inner-scope-host-part > div").shadowRoot.querySelector("#t12"); |
| assert_equals(getComputedStyle(t12).color, green); |
| }, "A :host::part rule should match containers in the originating element tree"); |
| |
| test(() => { |
| const target = document.querySelector("#named-part-host").shadowRoot.querySelector("#named-part1-child"); |
| assert_equals(getComputedStyle(target).color, green); |
| }, "Container name set inside a shadow tree should match query using ::part on the outside"); |
| |
| test(() => { |
| const target = document.querySelector("#named-part-host").shadowRoot.querySelector("#named-part2-child"); |
| assert_equals(getComputedStyle(target).color, green); |
| }, "Container name set with a ::part should match query inside the shadow tree"); |
| |
| test(() => { |
| const target = document.querySelector("#slotted1"); |
| assert_equals(getComputedStyle(target).color, green); |
| }, "Container name set inside a shadow tree should match query for a ::slotted() rule inside the tree"); |
| |
| test(() => { |
| const target = document.querySelector("#slotted2"); |
| assert_equals(getComputedStyle(target).color, green); |
| }, "Container name set inside a shadow tree should match query for host child on the outside"); |
| |
| test(() => { |
| const target = document.querySelector("#named-host").shadowRoot.querySelector("#host-descendant"); |
| assert_equals(getComputedStyle(target).color, green); |
| }, "Container name set on :host from inside a shadow tree matching query inside the shadow tree"); |
| |
| test(() => { |
| const target = document.querySelector("#host-slotted1"); |
| assert_equals(getComputedStyle(target).color, green); |
| }, "Container name set on :host from inside a shadow tree matching query for ::slotted inside the shadow tree"); |
| |
| test(() => { |
| const target = document.querySelector("#host-slotted2"); |
| assert_equals(getComputedStyle(target).color, green); |
| }, "Container name set on :host from inside a shadow tree should match query for slotted from the outside of the shadow tree"); |
| |
| test(() => { |
| const target = document.querySelector("#pseudo-1"); |
| assert_equals(getComputedStyle(target, "::before").color, green); |
| }, "The originating element should be the first container candidate of ::before"); |
| |
| test(() => { |
| const target = document.querySelector("#pseudo-2"); |
| assert_equals(getComputedStyle(target, "::before").color, green); |
| }, "Search flat tree anchestors of the originating element of ::before"); |
| </script> |