@@ -452,6 +452,87 @@ with a <<length>> or <<length-percentage>> syntax component:
452452 and ''font-size'' will behave as if the value ''unset'' was specified.
453453</div>
454454
455+ Shadow DOM {#shadow-dom}
456+ ------------------------
457+
458+ Unlike many concepts in CSS
459+ (see [[css-scoping-1#shadow-names]] ),
460+ property registrations are <strong> not</strong> scoped to a tree scope.
461+ All registrations,
462+ whether they appear in the outermost document
463+ or within a shadow tree,
464+ interact in a single global registration map for the {{Document}} .
465+
466+ <details class=note>
467+ <summary> Why can't registrations be scoped?</summary>
468+
469+ There are clear use-cases for property registrations to be scoped--
470+ a component using Shadow DOM
471+ and registering some custom properties
472+ for its own internal use
473+ probably doesn't intend for the outer page
474+ to see the registration,
475+ since the outer page doesn't even know the component is using that property.
476+
477+ However, there are also reasons to not scope the registration--
478+ custom properties are used to pipe data <em> into</em> a component,
479+ and it's useful for the outer page
480+ to be able to set such custom properties
481+ and have them syntax-checked by the registration;
482+ similarly, concepts such as a property's initial value
483+ don't make much sense
484+ unless the property registration exists globally,
485+ so it applies to the property even at the document's root.
486+
487+ But the above just means that registration scope
488+ might be something that should be controllable,
489+ not that it should be forced to be global.
490+
491+ The reason registrations must be global
492+ is because elements can exist in multiple tree scopes
493+ at the same time,
494+ with styles from each tree scope
495+ intermingling and cascading together.
496+ This applies to the [=host element=] ,
497+ which lives in the outer tree
498+ but is stylable from the shadow tree
499+ by the '':host'' selector,
500+ but also elements inside a shadow DOM
501+ that are targetable from the outer tree
502+ by the ''::part()'' pseudo-element.
503+
504+ If registrations could be scoped to a tree scope,
505+ and a single property was registered
506+ both inside and outside,
507+ it's not clear which registration should be applied
508+ to parse the value.
509+ Even if we tracked which tree a value came from
510+ (something we do for other tree-scoped values)
511+ and applied the corresponding registration,
512+ it's not clear that this would give a reasonable result--
513+ the shadow DOM might expect a property to have a particular value space,
514+ and be surprised when it receives something completely different
515+ due to the outer tree winning the cascade
516+ and applying its own registration.
517+ </details>
518+
519+ When custom properties are exposed
520+ as part of a Shadow DOM-using component's public API,
521+ this global registration behavior works as intended.
522+ If the outer page is using a custom property of the same name
523+ for different purposes,
524+ that is already a conflict that needs to be resolved,
525+ and the registration behavior does not make it worse.
526+
527+ If a custom property is intended for private internal usage for a component, however,
528+ it is recommended that the property
529+ be given a likely-unique name,
530+ to minimize the possibility of a clash with any other context.
531+ This can be done, for example,
532+ by including the project name,
533+ or some short random string of text,
534+ in the name of the property.
535+
455536
456537
457538<!--
0 commit comments