scope-shadow.html (5529B)
1 <!DOCTYPE html> 2 <title>@scope - ShadowDOM</title> 3 <link rel="help" href="https://drafts.csswg.org/css-cascade-6/#scope-atrule"> 4 <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/9025"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 8 <div id=host_plain> 9 <template shadowrootmode=open> 10 <style> 11 @scope (:host) { 12 .a { 13 z-index: 1; 14 } 15 } 16 </style> 17 <div class=a> 18 </div> 19 </template> 20 </div> 21 <script> 22 test(() => { 23 let a = host_plain.shadowRoot.querySelector('.a'); 24 assert_equals(getComputedStyle(a).zIndex, '1'); 25 }, '@scope can match :host'); 26 </script> 27 28 <div id=host_functional> 29 <template shadowrootmode=open> 30 <style> 31 @scope (:host(div)) { 32 .a { 33 z-index: 1; 34 } 35 } 36 /* Should not match: */ 37 @scope (:host(span)) { 38 .a { 39 z-index: 42; 40 } 41 } 42 </style> 43 <div class=a> 44 </div> 45 </template> 46 </div> 47 <script> 48 test(() => { 49 let a = host_functional.shadowRoot.querySelector('.a'); 50 assert_equals(getComputedStyle(a).zIndex, '1'); 51 }, '@scope can match :host(...)'); 52 </script> 53 54 <div id=host_scope_subject> 55 <template shadowrootmode=open> 56 <style> 57 @scope (:host) { 58 :scope { 59 z-index: 1; 60 } 61 } 62 </style> 63 <div class=a> 64 </div> 65 </template> 66 </div> 67 <script> 68 test(() => { 69 assert_equals(getComputedStyle(host_scope_subject).zIndex, '1'); 70 }, ':scope matches host via the scoping root'); 71 </script> 72 73 <div id=host_scope_subject_is> 74 <div class=host> 75 <template shadowrootmode=open> 76 <style> 77 /* Should not match host, nor outside shadow. */ 78 :is(:scope, .a, .host) { 79 z-index: 2; 80 } 81 82 @scope (:host) { 83 :is(:scope, .a) { 84 z-index: 1; 85 } 86 } 87 </style> 88 <div class=a> 89 </div> 90 </template> 91 </div> 92 <div class=a> 93 </div> 94 </div> 95 <script> 96 test(() => { 97 let host = host_scope_subject_is.querySelector('.host'); 98 assert_equals(getComputedStyle(host).zIndex, '1'); 99 let a = host.shadowRoot.querySelector('.a'); 100 assert_equals(getComputedStyle(a).zIndex, '1'); 101 102 let a_outside = host_scope_subject_is.querySelector('.a'); 103 assert_equals(getComputedStyle(a_outside).zIndex, 'auto'); 104 }, ':scope within :is() matches host via the scoping root'); 105 </script> 106 107 <div id=implicit_scope_shadow_parent> 108 <div class=host> 109 <template shadowrootmode=open> 110 <style> 111 @scope { 112 /* Matches host */ 113 :scope { 114 z-index: 1; 115 } 116 :scope > .a { 117 z-index: 2; 118 } 119 } 120 </style> 121 <div class=a> 122 </div> 123 </template> 124 </div> 125 </div> 126 <script> 127 test(() => { 128 let host = implicit_scope_shadow_parent.querySelector('.host'); 129 let a = host.shadowRoot.querySelector('.a'); 130 assert_equals(getComputedStyle(host).zIndex, '1'); 131 assert_equals(getComputedStyle(a).zIndex, '2'); 132 }, 'Implicit @scope as direct child of shadow root'); 133 </script> 134 135 <div id=implicit_scope_constructed> 136 <div class=host> 137 <template shadowrootmode=open> 138 <div class=a> 139 </div> 140 </template> 141 </div> 142 </div> 143 <script> 144 test(() => { 145 let host = implicit_scope_constructed.querySelector('.host'); 146 let sheet = new CSSStyleSheet(); 147 sheet.replaceSync(` 148 @scope { 149 :scope { 150 z-index: 1; 151 } 152 :scope .a { 153 z-index: 2; 154 } 155 `); 156 host.shadowRoot.adoptedStyleSheets = [sheet]; 157 let a = host.shadowRoot.querySelector('.a'); 158 assert_equals(getComputedStyle(host).zIndex, '1'); 159 assert_equals(getComputedStyle(a).zIndex, '2'); 160 }, 'Implicit @scope in construted stylesheet'); 161 </script> 162 163 <div id=scope_via_parent_pseudo_subject> 164 <div class=host> 165 <template shadowrootmode=open> 166 <style> 167 @scope (:host) { 168 :scope { 169 & { 170 z-index: 1; 171 } 172 } 173 } 174 </style> 175 </template> 176 </div> 177 </div> 178 <script> 179 test(() => { 180 let host = scope_via_parent_pseudo_subject.querySelector('.host'); 181 assert_equals(getComputedStyle(host).zIndex, '1'); 182 }, 'Matching :host via &, :scope (subject)'); 183 </script> 184 185 <div id=scope_via_parent_pseudo_non_subject> 186 <div class=host> 187 <template shadowrootmode=open> 188 <style> 189 @scope (:host) { 190 :scope .a { 191 & { 192 z-index: 1; 193 } 194 } 195 } 196 </style> 197 <div class=a> 198 </div> 199 </template> 200 </div> 201 </div> 202 <script> 203 test(() => { 204 let host = scope_via_parent_pseudo_non_subject.querySelector('.host'); 205 let a = host.shadowRoot.querySelector('.a'); 206 assert_equals(getComputedStyle(a).zIndex, '1'); 207 }, 'Matching :host via &, :scope (non-subject)'); 208 </script> 209 210 <div id=scope_via_parent_pseudo_non_subject_child> 211 <div class=host> 212 <template shadowrootmode=open> 213 <style> 214 @scope (:host) { 215 :scope > .a { 216 & { 217 z-index: 1; 218 } 219 } 220 } 221 </style> 222 <div class=a> 223 </div> 224 </template> 225 </div> 226 </div> 227 <script> 228 test(() => { 229 let host = scope_via_parent_pseudo_non_subject_child.querySelector('.host'); 230 let a = host.shadowRoot.querySelector('.a'); 231 assert_equals(getComputedStyle(a).zIndex, '1'); 232 }, 'Matching :host via &, :scope (non-subject, >)'); 233 </script>