Skip to content

Commit 9bb9de1

Browse files
committed
[css-shadow-parts][css-pseudo] Move various ::part() details to 'part-like pseudo-elements'. #10083
1 parent 376440d commit 9bb9de1

File tree

2 files changed

+134
-35
lines changed

2 files changed

+134
-35
lines changed

css-pseudo-4/Overview.bs

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,27 +1305,47 @@ Tree-Abiding and Part-Like Pseudo-elements</h2>
13051305
parsing/tree-abiding-pseudo-elements.html
13061306
</wpt>
13071307

1308+
<h3 id=partlike>
1309+
Part-Like Pseudo-Elements</h3>
1310+
13081311
A subset of [=tree-abiding pseudo-elements=],
1309-
the <dfn>part-like pseudo-elements</dfn>,
1312+
the <dfn export lt="part-like|part-like pseudo-element">part-like pseudo-elements</dfn>,
13101313
have slightly stronger requirements:
13111314
they act as if they have a well-defined location in the document tree.
13121315
This enables them to interact with some other platform features
1313-
as if they were real elements.
1314-
1315-
<div class=example>
1316-
For example, a [=part-like pseudo-element=]
1317-
can be used in the <{html-global/exportparts}> attribute,
1318-
to masquerade as a ''::part()''
1319-
for the component it's in:
1320-
1321-
<xmp class=html>
1322-
<template id=custom-element-template>
1323-
<p exportparts="::before : preceding-text">
1324-
You can style my ::before pseudo-element
1325-
by using ::part(preceding-text), too!
1326-
</template>
1327-
</xmp>
1328-
</div>
1316+
as if they were real elements
1317+
(and, in fact, they often <em>are</em> real elements,
1318+
such as in the case of ''::part()'',
1319+
which simply aren't accessible in the current tree).
1320+
1321+
[=Part-like pseudo-elements=] inherit from their [=originating element=] by default,
1322+
like a standard [=tree-abiding pseudo-element=],
1323+
but can declare that they inherit from another element instead
1324+
(possibly not accessible).
1325+
(For example, ''::part()'' inherits from
1326+
the parent of the element it represents in the shadow tree.)
1327+
1328+
All pseudo-classes and pseudo-elements
1329+
are syntactically allowed after a [=part-like pseudo-element=],
1330+
such as ''x-button::part(label):hover''
1331+
or ''x-button::part(label)::before'',
1332+
but some are disallowed from matching:
1333+
1334+
* The [=structural pseudo-classes=],
1335+
'':has()'' pseudo-class,
1336+
'':scope'' pseudo-class,
1337+
and '':host''/'':host()''/'':host-context()'' pseudo-classes
1338+
never match.
1339+
* ''::part()'' never matches. (Other [=part-like pseudo-elements=] can, however.)
1340+
1341+
A [=part-like pseudo-element=] can define itself as representing a real element
1342+
(possibly not accessible in the current tree).
1343+
If it does so, all pseudo-classes and pseudo-elements match according to that element,
1344+
if not disallowed by the previous restrictions.
1345+
If it does not do so,
1346+
it must define which pseudo-classes it matches and when
1347+
(besides the pseudo-classes defined to work on all pseudo-elements,
1348+
or all [=tree-abiding pseudo-elements=]).
13291349

13301350
Unless otherwise specified,
13311351
any CSS property that applies to elements

css-shadow-parts-1/Overview.bs

Lines changed: 97 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,16 @@ from the sub-parts that it merely happens to contain,
109109
it also helps with encapsulation,
110110
as authors can use ''::part()'' without fear of accidental over-styling.
111111

112-
112+
<!-- Big Text: parts
113+
114+
████▌ ███▌ ████▌ █████▌ ███▌
115+
█▌ █▌ ▐█ ▐█ █▌ █▌ █▌ █▌ █▌
116+
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌
117+
████▌ █▌ █▌ ████▌ █▌ ███▌
118+
█▌ █████▌ █▌▐█ █▌ █▌
119+
█▌ █▌ █▌ █▌ ▐█ █▌ █▌ █▌
120+
█▌ █▌ █▌ █▌ █▌ █▌ ███▌
121+
-->
113122
Exposing a Shadow Element: {#exposing}
114123
=============================================================
115124
Elements in a <a>shadow tree</a> may be exported for styling by stylesheets outside the tree
@@ -146,12 +155,25 @@ and changes to the [=part name lists=] and [=forwarded part name lists=] of elem
146155
then let |innerRoot| be its shadow root.
147156
3. [=calculate the part element map|Calculate=] |innerRoot|'s [=part element map=].
148157
4. For each |innerName|/|outerName| in |el|'s [=forwarded part name list=]:
149-
1. Let |innerParts| be |innerRoot|'s [=part element map=][|innerName|]
150-
2. [=list/Append=] the elements in |innerParts|
151-
to |outerRoot|'s [=part element map=][|outerName|]
158+
1. If |innerName| is an ident:
159+
1. Let |innerParts| be |innerRoot|'s [=part element map=][|innerName|]
160+
2. [=list/Append=] the elements in |innerParts|
161+
to |outerRoot|'s [=part element map=][|outerName|]
162+
2. If |innerName| is a pseudo-element name:
163+
1. [=list/Append=] |innerRoot|'s pseudo-element(s) with that name
164+
to |outerRoot|'s [=part element map=][|outerName|].
152165
</div>
153166

167+
<!-- Big Text: part=""
154168

169+
████▌ ███▌ ████▌ █████▌ ▐█▌ ▐█▌ ▐█▌ ▐█▌
170+
█▌ █▌ ▐█ ▐█ █▌ █▌ █▌ ▐█▌ ▐█▌ ▐█▌ ▐█▌
171+
█▌ █▌ █▌ █▌ █▌ █▌ █▌ ████ █ █ █ █
172+
████▌ █▌ █▌ ████▌ █▌
173+
█▌ █████▌ █▌▐█ █▌ ████
174+
█▌ █▌ █▌ █▌ ▐█ █▌
175+
█▌ █▌ █▌ █▌ █▌ █▌
176+
-->
155177
Naming a Shadow Element: the <{html-global/part}> attribute {#part-attr}
156178
------------------------------------------------------------------------
157179

@@ -179,6 +201,16 @@ not an id or tagname.
179201
&lt;/script>
180202
</pre>
181203

204+
<!-- Big Text: exportparts
205+
206+
█████▌ █ █ ████▌ ███▌ ████▌ █████▌ ████▌ ███▌ ████▌ █████▌ ███▌
207+
█▌ █ █ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ ▐█ ▐█ █▌ █▌ █▌ █▌ █▌
208+
█▌ █ █ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌
209+
████ █ ████▌ █▌ █▌ ████▌ █▌ ████▌ █▌ █▌ ████▌ █▌ ███▌
210+
█▌ █ █ █▌ █▌ █▌ █▌▐█ █▌ █▌ █████▌ █▌▐█ █▌ █▌
211+
█▌ █ █ █▌ █▌ █▌ █▌ ▐█ █▌ █▌ █▌ █▌ █▌ ▐█ █▌ █▌ █▌
212+
█████▌ █ █ █▌ ███▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ ███▌
213+
-->
182214
Forwarding a Shadow Element: the <{html-global/exportparts}> attribute {#exportparts-attr}
183215
----------------------------------------------------------------------------------
184216
Any element in a shadow tree can have a <dfn element-attr for=html-global>exportparts</dfn> attribute.
@@ -200,6 +232,12 @@ Each part mapping is one of:
200232

201233
Note: This is shorthand for <code>ident : ident</code>.
202234

235+
: <code>::ident : outerIdent</code>
236+
:: If <code>::ident</code> is the name of a [=part-like pseudo-element=],
237+
adds <code>::ident</code>/<code>outerIdent</code>
238+
to el's [=forward part name list=].
239+
Otherwise, does nothing.
240+
203241
: anything else
204242
:: Ignored for error-recovery / future compatibility.
205243
</dl>
@@ -235,8 +273,40 @@ Note: It's okay to map a sub-part to several names.
235273
&lt;/script>
236274
</pre>
237275

276+
<div class=example>
277+
For example, a [=part-like pseudo-element=]
278+
can be used in the <{html-global/exportparts}> attribute,
279+
to masquerade as a ''::part()''
280+
for the component it's in:
281+
282+
<xmp class=html>
283+
<template id=custom-element-template>
284+
<p exportparts="::before : preceding-text, ::after : following-text">
285+
Main text.
286+
</template>
287+
</xmp>
288+
289+
An element using that template
290+
can use a selector like ''x-component::part(preceding-text)''
291+
to target the ''p::before'' pseudo-element in its shadow,
292+
so users of the component don't need to know
293+
that the preceding text is implemented as a pseudo-element.
294+
</div>
295+
296+
297+
<!-- Big Text: ::part()
298+
299+
█▌ █▌ ████▌ ███▌ ████▌ █████▌ ██ ██
300+
███▌ ███▌ █▌ █▌ ▐█ ▐█ █▌ █▌ █▌ █▌ ▐█
301+
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ ▐█
302+
████▌ █▌ █▌ ████▌ █▌ █▌ ▐█
303+
█▌ █▌ █▌ █████▌ █▌▐█ █▌ █▌ ▐█
304+
███▌ ███▌ █▌ █▌ █▌ █▌ ▐█ █▌ █▌ ▐█
305+
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ ██ ██
306+
-->
307+
238308
Selecting a Shadow Element: the ''::part()'' pseudo-element {#part}
239-
============================================================================================
309+
===================================================================
240310

241311
The <dfn selector>::part()</dfn> pseudo-element
242312
allows you to select elements that have been exposed via a <{html-global/part}> attribute.
@@ -248,18 +318,14 @@ The syntax is:
248318

249319
The ''::part()'' pseudo-element only matches anything
250320
when the <a>originating element</a> is a <a>shadow host</a>.
251-
If the <a>originating element's</a> <a>shadow root's</a> <a>part element map</a>
252-
[=map/contains=] all of the specified <<ident>>s,
253-
''::part()'' matches the element or elements keyed to that <<ident>>.
254-
Otherwise, it matches nothing.
255321

256322
<div class="example">
257323
For example,
258324
if you have a custom button
259325
that contains a "label" element that is exposed for styling
260326
(via <code>part="label"</code>),
261327
you can select it with
262-
''#the-button::part(label)''.
328+
''x-button::part(label)''.
263329
</div>
264330

265331
<div class="example">
@@ -277,15 +343,16 @@ Otherwise, it matches nothing.
277343
(or ''::part(active tab)'', as order doesn't matter).
278344
</div>
279345

280-
The ''::part()'' pseudo-element can take additional pseudo-classes after it,
281-
such as ''x-button::part(label):hover'',
282-
but never matches the <a>structural pseudo-classes</a>
283-
or any other pseudo-classes that match based on tree information
284-
rather than local element information.
346+
The ''::part()'' pseudo-element is a [=part-like pseudo-element=].
347+
If the <a>originating element's</a> <a>shadow root's</a> <a>part element map</a>
348+
[=map/contains=] the specified <<ident>>,
349+
''::part()'' represents the elements keyed to that ident;
350+
if multiple idents are provided and the [=part element map=] contains them all,
351+
it represents the intersection of the elements keyed to each ident.
352+
Otherwise, it matches nothing.
285353

286-
The ''::part()'' pseudo-element can also take additional pseudo-elements after it,
287-
such as ''x-button::part(label)::before'',
288-
but never match additional ''::part()''s.
354+
''::part()'' pseudo-elements inherit according to their position
355+
in the [=originating element's=] shadow tree.
289356

290357
<div class=example>
291358
For example,
@@ -303,6 +370,18 @@ but never match additional ''::part()''s.
303370
ignoring any other labels.
304371
</div>
305372

373+
374+
<!-- Big Text: CSSOM
375+
376+
███▌ ███▌ ███▌ ███▌ █ █
377+
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ ██ ██
378+
█▌ █▌ █▌ █▌ █▌ █▌█ █▐█
379+
█▌ ███▌ ███▌ █▌ █▌ █▌ █ ▐█
380+
█▌ █▌ █▌ █▌ █▌ █▌ ▐█
381+
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ ▐█
382+
███▌ ███▌ ███▌ ███▌ █▌ ▐█
383+
-->
384+
306385
Extensions to the {{Element}} Interface {#idl}
307386
==============================================
308387

0 commit comments

Comments
 (0)