@@ -452,6 +452,87 @@ with a <<length>> or <<length-percentage>> syntax component:
452
452
and ''font-size'' will behave as if the value ''unset'' was specified.
453
453
</div>
454
454
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
+
455
536
456
537
457
538
<!--
0 commit comments