-
Notifications
You must be signed in to change notification settings - Fork 708
/
Copy pathOverview.bs
441 lines (356 loc) · 15.4 KB
/
Overview.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
<pre class='metadata'>
Title: CSS Scoping Module Level 2
Level: 2
Shortname: css-scoping
Group: CSSWG
Status: ED
Work Status: Exploring
TR: https://www.w3.org/TR/css-scoping-1/
ED: https://drafts.csswg.org/css-scoping/
Editor: Tab Atkins Jr., Google, http://xanthir.com/contact/, w3cid 42199
Editor: Miriam E. Suzanne, Invited Expert, http://miriamsuzanne.com/contact, w3cid 117151
Abstract: This specification defines scoping/encapsulation mechanisms for CSS.
Ignored Terms: inherit, slot, custom elements, stylesheets
Ignored Vars: root elements
</pre>
<pre class="link-defaults">
spec:dom; type:dfn;
text:host
text:shadow root; for:/
text:root; for:tree
text:find slottables
text:find flattened slottables
text:element; for:/
spec:html; type:element; text:style
spec:selectors-4; type:dfn;
text: static profile
text: dynamic profile
spec:css-pseudo-4; type:selector;
text:::before
text:::after
spec:cascade-4; type:dfn; text: inherit
</pre>
<h2 id="intro">
Introduction</h2>
Issue: This is a diff spec over <a href="https://www.w3.org/TR/css-scoping-1/">CSS Scoping Module Level 1</a>.
It is currently an Exploratory Working Draft:
if you are implementing anything, please use Level 1 as a reference.
We will merge the Level 1 text into this draft once it reaches CR.
<!--
████████ ████████ ████████ ███ ██ ██ ██ ████████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██████ ██████ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ █████████ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
████████ ████████ ██ ██ ██ ███████ ████████ ██
-->
<h2 id='default-element-styles'>
Default Styles for Custom Elements</h2>
Issue: [[css-scoping-1#default-element-styles]]
<!--
██████ ██ ██ ███ ████████ ███████ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██████ █████████ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ █████████ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██████ ██ ██ ██ ██ ████████ ███████ ███ ███
-->
<h2 id='shadow-dom'>
Shadow Encapsulation</h2>
Issue: [[css-scoping-1#shadow-dom]]
<!--
██████ ██████ ███████ ████████ ████ ██ ██ ██████
██ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ████ ██ ██
██████ ██ ██ ██ ████████ ██ ██ ██ ██ ██ ████
██ ██ ██ ██ ██ ██ ██ ████ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ ██
██████ ██████ ███████ ██ ████ ██ ██ ██████
-->
<h2 id='scoped-styles'>
Scoped Styles</h2>
A <dfn>scope</dfn> is a subtree or fragment of a document,
which can be used by selectors for more targeted matching.
[=Scopes=] are described in CSS through a combination of two selector lists:
* The <dfn><<scope-start>></dfn> is a <<forgiving-selector-list>>.
Each element matched by <<scope-start>> is a [=scoping element=],
creating a scope with itself as the [=scoping root=].
* The <dfn><<scope-end>></dfn> is a <<forgiving-selector-list>>
that is [=scoped selector|scoped=] by the <<scope-start>> selector,
with the [=scoping roots=] as [=:scope elements=].
Each element matched by <<scope-end>> is a [=scope boundary=].
<dfn>Scope boundary</dfn> elements provide lower bounds to a scope,
so that [=scoped selectors=] are not able to match more deeply nested elements.
Note: This means that the '':scope'' pseudo-class
in a lower boundary (<<scope-end>>) selector
will always refer to the [=scope=] being described,
rather than the outer scope context.
<div class=example>
For example,
[=scope boundaries=] can be contextual:
<pre class=lang-css>
/* .content is only a boundary when the :scope is inside .sidebar */
@scope (.media-object) to (.sidebar :scope .content) {
img { border-radius: 50%; }
}
</pre>
Or based on a specific relationship to the [=scoping root=]:
<pre class=lang-css>
/* .content is only a boundary when it is a direct child of the :scope */
@scope (.media-object) to (:scope > .content) {
img { border-radius: 50%; }
}
</pre>
</div>
Each resulting [=scope=] includes a [=scoping root=] and all its descendants,
up to and including any [=scope boundary=] elements,
but not the descendants of those boundaries.
In contrast to <a href="#shadow-dom">Shadow Encapsulation</a>,
which describes a persistent one-to-one relationship in the DOM
between a [=shadow host=] and its nested [=shadow tree=],
multiple overlapping [=scopes=] can be defined in relation to the same elements.
<div class=example>
For example,
An author might have wide-reaching color-scheme scopes,
which overlap more narrowly defined design patterns
such as a media object:
<pre class=lang-css>
@scope (.light-scheme) {
a { color: darkmagenta; }
}
@scope (.dark-scheme) {
a { color: plum; }
}
@scope (.media-object) {
.media-image { border-radius: 50%; }
.media-content { padding: 1em; }
}
</pre>
</pre>
</div>
<div class=example>
By providing [=scope boundaries=],
an author can limit matching more deeply nested descendants.
For example:
<pre class=lang-css>
@scope (.media-object) to (.content) {
img { border-radius: 50%; }
/* it is also possible to style the lower boundary itself */
.content { padding: 1em; }
}
</pre>
The ''img'' selector will only match image tags that are inside a ''.media-object'',
without any intervening ''.content'' class between it and the [=scoping root=].
</div>
<!--
██ ████ ██ ██
████ ██ ███ ██
██ ██ ████ ██
██ ██ ██ ██
██ ██ ██ ████
████ ██ ██ ███
██ ████ ██ ██
-->
<h3 id='in-scope-selector'>
The in-scope pseudo-class '':in()''</h3>
The in-scope pseudo-class, <dfn>:in()</dfn>,
is a functional pseudo-class with the following syntax:
<pre class='prod'>
:in(<<scope-start>> [/ <<scope-end>>]?)
</pre>
If, after parsing, <<scope-start>> is an empty list,
the pseudo-class is valid but matches nothing, and defines no scopes.
Otherwise, the pseudo-class matches any element that is in a [=scope=]
described by the given <<scope-start>> and <<scope-end>> selectors.
Note: This does not effect the [=:scope elements=] for the selector.
The specificity of the '':in()'' pseudo-class
is replaced by the specificity of
the most specific [=complex selector=] in its <<scope-start>> argument.
<div class=example>
The purpose of the in-scope pseudo-class
is to allow adding [=scope boundaries=] to a selector:
<pre class=lang-css>
.title:in(.post / .comments) { font-size: 2em; }
</pre>
Without any such lower boundaries,
the ''in()'' pseudo-class is similar to other existing selectors.
These three selectors will all select the same elements,
with the same specificity:
<pre class=lang-css>
.child:in(.ancestor) { color: darkmagenta; }
.child:is(.ancestor, .ancestor *) { color: darkmagenta; }
.ancestor.child, .ancestor .child { color: darkmagenta; }
</pre>
</div>
<!--
███████ ██████ ██████ ███████ ████████ ████████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ███ ██ ██ ██ ██ ██ ██ ██ ██
██ ███ ██ ██████ ██ ██ ██ ████████ ██████
██ █████ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██
███████ ██████ ██████ ███████ ██ ████████
-->
<h3 id='scope-atrule'>
Scoping Styles in CSS: the ''@scope'' rule</h3>
The <dfn at-rule id="at-ruledef-layer">@scope</dfn> [=block at-rule=]
allows authors to create scoped stylesheets in CSS,
with the addition of [=scope proximity=] weighting in the cascade.
The syntax of the ''@scope'' rule is:
<pre class='prod'>
@scope (<<scope-start>>) [to (<<scope-end>>)]? {
<<stylesheet>>
}
</pre>
The ''@scope'' rule has three primary effects on the style rules in <<stylesheet>>.
For each [=scope=] that is described by the given <<scope-start>> and <<scope-end>>:
* [=scoped selectors|Selectors are scoped=] to the [=scope=] in question,
with the [=:scope element=] being the [=scoping root=].
* Selectors are given the added specificity of
the most specific [=complex selector=] in the <<scope-start>> argument.
This is designed to match the behavior of the '':in()'' and '':is()'' selectors.
* The cascade prioritizes rules with a [=scope proximity|more proximate=] [=scoping root=],
regardless of source order.
<div class=example>
The following selectors have the same specificity (1,0,1):
<pre class=lang-css>
#hero img { border-radius: 50%; }
@scope (#hero) {
img { border-radius: 50%; }
}
</pre>
</div>
<div class=example>
Many existing tools implement "scoped styles"
by applying a unique class or attribute
to every element in a given scope
or "single file component."
In this example there are two scopes
(<code>main-component</code> and <code>sub-component</code>)
and every element is marked as part of one or both scopes
using the <code>data-scope</code> attribute:
<pre class=lang-html>
<section data-scope="main-component">
<p data-scope="main-component">...<p>
<!-- sub-component root is in both scopes -->
<section data-scope="main-component sub-component">
<!-- children are only in the inner scope -->
<p data-scope="sub-component">...<p>
</section>
</section>
</pre>
Those custom scope attributes are then
appended to every single selector in CSS:
<pre class=lang-css>
p[data-scope~='main-component'] { color: red; }
p[data-scope~='sub-component'] { color: blue; }
/* both sections are part of the outer scope */
section[data-scope~='main-component'] { background: snow; }
/* the inner section is also part of the inner scope */
section[data-scope~='sub-component'] { color: ghostwhite; }
</pre>
Using the ''@scope'' rule,
authors and tools can replicate similar behavior
with the unique attribute or class
applied only to the [=scoping roots=]:
<pre class=lang-html>
<section data-scope="main-component">
<p>...<p>
<section data-scope="sub-component">
<!-- children are only in the inner scope -->
<p>...<p>
</section>
</section>
</pre>
Then the class or attribute can be used
for establishing both upper and lower boundaries,
such that scopes only overlap at those boundaries:
<pre class=lang-css>
@scope ([data-scope='main-component']) to ([data-scope]) {
p { color: red; }
/* both sections are part of the outer scope */
section { background: snow; }
}
@scope ([data-scope='sub-component']) to ([data-scope]) {
p { color: blue; }
/* the inner section is also part of the inner scope */
section { color: ghostwhite; }
}
</pre>
</div>
''@scope'' rules can be nested.
In this case, just as with the nested style rules,
the selectors of the inner ''@scope'' are [=scoped selectors|scoped by=]
the selectors of the outer one.
<h4 id='scope-cascade'>
Scope Proximity in the Cascade</h3>
Issue: This likely belongs in the css-cascade specification.
<dfn>Scope proximity</dfn> is considered in the cascade sort order
after specificity, and before order of appearance.
If the [=:scope elements=] of two declarations
have an ancestor/descendant relationship,
then the declaration whose [=:scope element=] is the descendant wins.
Note: When the [=:scope element=] is not otherwise defined for a declaration,
it is the document root element.
<div class=example>
When scoped declarations overlap—
applying to the same elements
with the same cascade origin, importance, layer, and specificity—
then one with closer [=scope proximity=] takes precedence.
For example, this ''light-scheme'' and ''dark-scheme'' scopes:
<pre class=lang-css>
@scope (.light-scheme) {
a { color: darkmagenta; }
}
@scope (.dark-scheme) {
a { color: plum; }
}
</pre>
If ''light-scheme'' and ''dark-scheme'' classes are nested in the DOM,
whichever is closer to a given link in the DOM tree
will take precedence for styling that link,
regardless of their order of appearance in CSS:
<pre class=lang-html>
<section class="light-scheme">
<a href="#">
light scope:
darkmagenta link color
</a>
<aside class="dark-scheme">
<a href="#">
both scopes, but dark-scheme is a closer ancestor:
plum link color
</a>
</aside>
</section>
</pre>
</div>
<h2 id="changes">
Changes</h2>
<h3 id="additions-l">
Additions Since Level 1</h3>
The following features have been added since
<a href="https://www.w3.org/TR/css-scoping-1/">Level 1</a>:
* The definition of a [=scope=],
as described by a combination of <<scope-start>> and <<scope-end>> selectors.
* The in-scope ('':in()'') pseudo-class for selecting with lower-boundaries
* The ''@scope'' rule for creating scoped stylesheets
* The definition of [=scope proximity=] in the cascade
<h2 class="no-num" id="acknowledgments">Acknowledgments</h2>
Elika J. Etemad / fantasai,
Giuseppe Gurgone,
Keith Grant,
Lea Verou,
Nicole Sullivan,
and Theresa O'Connor
contributed to this specification.
Privacy and Security Considerations {#priv-sec}
===============================================
This specification introduces Shadow DOM and some shadow-piercing capabilities,
but this does not introduce any privacy or security issues--
shadow DOM, as currently specified, is intentionally not a privacy/security boundary
(and the parts of the UA that use shadow DOM and <em>do</em> have a privacy/security boundary
implicitly rely on protections not yet specified,
which protect them from the things defined in this specification).