@@ -541,6 +541,151 @@ Slots and Slotted Elements in a Shadow Tree</h4>
541541 and any deeper <a>slots</a> that their <a>slot</a> gets assigned to,
542542 don't affect inheritance.
543543
544+
545+ <h3 id='shadow-names'>
546+ Name-Defining Constructs and Inheritance</h3>
547+
548+ [=Shadow trees=] are meant to be an encapsulation boundary,
549+ allowing independent authors to share code
550+ without accidentally polluting each other's namespaces.
551+ For example, element IDs,
552+ which are generally meant to be unique within a document,
553+ can be validly used multiple times
554+ as long as each use is in a different [=shadow tree=] .
555+
556+ Similarly, several [=at-rules=] in CSS,
557+ such as ''@keyframes'' or ''@font-face'' ,
558+ define a name that later at-rules or properties can refer to them by.
559+ Like IDs, these names are globally exposed and unique within a document;
560+ also like IDs,
561+ this restriction is now loosened to being unique within a given [=shadow tree=] .
562+
563+ However, property inheritance can carry values from one tree to another,
564+ which complicates referencing the correct definition of a given name.
565+ Done naively, this can produce surprising and confusing results for authors.
566+ This section defines a set of concepts to use in defining and referencing "global" names
567+ in a way that respects encapsulation
568+ and doesn't give surprising results.
569+
570+ If an at-rule or property defines a name that other CSS constructs can refer to it by,
571+ such as a 'font-family!!descriptor' name
572+ or an ''@keyframes'' name,
573+ it must be defined as a <dfn export for=CSS>tree-scoped name</dfn> .
574+ [=Tree-scoped names=] are "global" within a particular [=node tree=] ;
575+ unless otherwise specified,
576+ they're associated with the [=root=] of the [=element=] hosting the stylesheet that the at-rule or property is defined in.
577+
578+ Properties or descriptors that reference a "global" name,
579+ such as the 'font-family!!property'
580+ or 'animation-name' properties,
581+ must define their value as a <dfn export for=CSS>tree-scoped reference</dfn> .
582+ [=Tree-scoped references=] implicitly capture
583+ a [=node tree=] [=root=]
584+ along with their specified value:
585+ unless otherwise specified,
586+ the [=root=] of the [=element=] hosting the stylesheet that the property or descriptor is defined in.
587+ This [=root=] reference stays with the [=tree-scoped reference=]
588+ as it is inherited.
589+
590+ Whenever a [=tree-scoped reference=] is dereferenced
591+ to find the CSS construct it is referencing,
592+ only the [=tree-scoped names=] associated with the same [=root=]
593+ as the [=tree-scoped reference=] must be searched.
594+
595+ <div class=issue>
596+ TODO: Fix all the at-rules that define global names,
597+ and the properties that reference them,
598+ to use these concepts.
599+
600+ * ''@font-face'' , referenced by 'font-family!!property'
601+ * ''@font-feature-values'' , referenced by 'font-family!!property'
602+ * ''@keyframes'' , referenced by 'animation-name'
603+ * ''@counter-style'' , referenced by 'list-style-type'
604+ * ''@color-profile'' , referenced by the ''color()'' function
605+ * ''@font-palette-values'' , referenced by 'font-palette'
606+ * others?
607+ </div>
608+
609+ <h4 id='shadow-names-serialization'>
610+ Serialized Tree-Scoped References</h4>
611+
612+ If a [=tree-scoped reference=] is [=serialized=] ,
613+ it serializes only its value;
614+ the associated [=root=] is lost.
615+
616+ <div class=example>
617+
618+ This implies that `el.style.foo = getComputedStyle(el).foo;`
619+ is not necessarily a no-op,
620+ like it typically was before [=shadow trees=] existed.
621+
622+ For example,
623+ given the following document
624+ (using the imaginary <::shadow></::shadow> markup
625+ to indicate an element's [=shadow tree=] ):
626+
627+ <xmp highlight=markup>
628+ <p class=outer> Here's some text in the outer document's "foo" font.
629+ <style>
630+ @font-face {
631+ font-family: foo;
632+ src: url(foo.woff);
633+ }
634+ .outer { font-family: foo; }
635+ </style>
636+
637+ <my-component>
638+ <::shadow>
639+ <p class=inner-default> I'm inheriting the outer document's font-family.
640+ <p class=inner-styled> And I'm explicitly styled to be in the component's "foo" font.
641+ <style>
642+ @font-face {
643+ font-family: foo;
644+ src: url(https://example.com/foo.woff);
645+ }
646+ .inner-styled { font-family: foo; }
647+ </style>
648+ <script>
649+ const innerDefault = document.querySelector('.inner-default' );
650+ const innerStyled = document.querySelector('.inner-styled' );
651+ const defaultFont = getComputedStyle(innerDefault).fontFamily;
652+ const styledFont = getComputedStyle(innerStyled).fontFamily;
653+
654+ console.log(defaultFont == styledFont); // true!
655+ </script>
656+ </::shadow>
657+ </my-component>
658+ </xmp>
659+
660+ The <code> .outer</code> element is styled with the outer document's "foo" ''@font-face'' .
661+ The <code> .inner-default</code> element inherits 'font-family' from the outer document,
662+ meaning it inherits a [=tree-scoped reference=]
663+ referencing that outer document,
664+ and so it's in the same font as <code> .outer</code> .
665+
666+ Meanwhile, <code> .inner-styled</code> is explicitly styled from inside the shadow root,
667+ so it receives a fresh [=tree-scoped reference=]
668+ referencing its shadow tree,
669+ and it is instead styled the shadow's own "foo" ''@font-face'' .
670+
671+ Despite that, the script running inside the component
672+ sees the two elements as having the same value for 'font-family' ,
673+ because the [=root=] -reference part of a [=tree-scoped reference=]
674+ is not preserved by serialization.
675+ If it were to set <code highlight=js> innerDefault.style.fontFamily = defaultFont;</code>
676+ (thus setting the 'font-family' property of the element's attribute stylesheet,
677+ which lives in the shadow tree),
678+ the <code> .inner-default</code> element would suddenly switch
679+ to the same font as <code> .inner-styled</code> !
680+ </div>
681+
682+ Note: The [[css-typed-om-1]] is expected to reflect the [=root=] reference of a [=tree-scoped reference=]
683+ in its [=reification=] rules for values,
684+ allowing authors to tell what [=node tree=] the reference is taking its values from,
685+ and allowing values to be transported across [=node trees=]
686+ without changing their meaning.
687+
688+
544689<h2 id="changes">
545690Changes</h2>
546691
0 commit comments