XBL Task Force Issue: CSS Selectors and Shadow Content

This version:
Version 0.2: 2005/01/03
Previous versions:
Version 0.1: 2004/12/08

Abstract

This document is a working document within the XBL task force which discusses one of the outstanding issues in depth: how do CSS selectors match against elements that are part of the "shadow content" (quoted because there are actually multiple possible definitions of "shadow content").

Table of contents


1 Introduction

The latest draft of sXBL (22Nov2004) includes the following request for public feedback:

Request for public feedback

There is an open technical issue regarding CSS selector processing on shadow trees. Should selectors match only based on Core DOM parent-child links, ignoring XBL DOM links both in the bound document and the xblShadowTree subtree; or should they match against just the flattened tree traversals at each scope; or always match against both; or provide a switch to match against either?

Within the Binding Task Force, there is general agreement on the following:

The major open question is the tree topology that should be used for CSS selector matching. Here are some specific questions:

  1. Should CSS selector matching follow Core DOM traversals (i.e., the DOM3 Core standard tree traversal facilities such as firstChild, nextSibling, parentNode, etc.)? [Relative to this issue about how selectors should work against shadow content, this translates into matching against the topology of xblShadowTree.]
  2. Or should CSS selectors match against the fully flattened tree as represented by xblChildNodes?
  3. Or should CSS selectors match against xblScopedChildNodes?
  4. Should CSS selectors traverse both the Core DOM tree and one of the shadow tree topologies?
  5. Should there be options which allow content developers to choose among different traversal schemes?
  6. Should selectors be able to "cross boundaries" from the bound element to its shadow tree and from the shadow tree to elements referenced by <xbl:content> elements?

The proposals below attempt to provide answers to these questions.

2 Background

2.1 How Mozilla XBL does it

Mozilla XBL includes a section titled Anonymous Content and CSS which includes the following text:

4.6.1. Selectors and Scopes

Bindings can interleave anonymous elements between the bound element and its explicit children. See 4.4. Insertion Points for more information. In this situation, a new tree emerges that is different from the explicit content node tree. In addition to having a single explicit parent (the bound element) the explicit children also have an arbitrary set of anonymous parents (created by bindings when child insertion points or element tags were used). Child, descendant and sibling selectors will match on any path of anonymous and explicit elements.

As far as CSS is concerned, anonymous content nodes are children (or descendants) of the bound element, they are ancestors of explicit content, and they are siblings of the explicit content. Style rules using the child, descendant or sibling selectors transparently cross binding scopes and operate on the altered and original content models.

The final modified content tree determines how CSS properties (e.g., fonts and colors) are inherited. An element either ends up underneath its explicit parent (just as in the content model), or it ends up being nested through a series of insertion points. When nested, it inherits from the innermost anonymous parent.

4.6.2. Binding Stylesheets

A binding file can load stylesheets using the stylesheet element. By default these stylesheets apply to the bound element and to all anonymous content generated by all bindings attached to the bound element. These sheets have the same origin as the sheet with the rule responsible for the binding. Stylesheets loaded by bindings that are attached using the DOM are treated as author-level sheets.

[Editor's Note: Binding inheritance complicates this cascade, since an author-level DOM binding could inherit from a user-level binding. If both load sheets, what level do those sheets belong to in the cascade?]

Sheets are always walked from the innermost scope to the outermost scope. With this ordering a binding that defines a widget can define a default look for the widget that can then be easily overridden by a client of the widget. For multiple bindings attached to the same element, the sheets are walked from the base binding down to the most derived binding.

Bindings can fine-tune the control of the stylesheet scoping with two attributes. The first, applyauthorstyles, indicates whether or not author sheets defined at outer scopes affect the anonymous content generated by the binding. For the primary generating binding only, this attribute is checked to see if any author sheets at outer levels of scoping should be applied to the anonymous content generated by the bindings attached to the bound element. If this attribute is set, the rules specified in any author sheets at outer scopes are not walked.

By default, stylesheets specified in bindings files are applied only to the bound element and to anonymous content generated by bindings attached to the element. A second attribute, styleexplicitcontent can be used to indicate that all children of the bound element, both anonymous and explicit, can be styled by the sheets in the binding's document.

User agent sheets and user sheets are always applied to all scopes.

The proposal in 4.1 is an evolved form of the behaviour specified in Mozilla XBL.

2.2 How RCC did it

The description of RCC only says that CSS styling rules are an open issue. Adobe's early implementation of RCC applied selectors using Core DOM traversals, which is a proper subset of Proposal 2.

3 Possible Requirements

The following are possible additional requirements on the definition of XBL that came up during discussion of this issue:

  1. Simplicity and understandability. Should the processing model for any parts of sXBL, particularly the processing model for CSS selectors, have sufficient simplicity to allow reasonably quick understanding? (classify as a MUST?) [XBL-TF open question: Or is understanding of the model not as important as an intuitive result?]
  2. Reliability and predictability, minimization of surprises and side-effects. Should the processing model for any parts of sXBL, particularly the processing model for CSS selectors, be such that content developers who use XBL components achieve reliable and predictable behavior without surprising results in unusual cases? Should the sXBL processing model be such that component developers can readily deliver components that will perform reliably without surprises in unusual cases? (classify as a MUST?)
  3. Provide an option for complete sXBL component encapsulation. Should the feature set for sXBL, particularly the processing model for CSS selectors, offer the ability for sXBL components which have black-box, information-hiding/encapsulation approaches which are the cornerstone of object-oriented programming? (classify as a MUST?)
  4. XBL2: Provide an option that allows bound element children to be styled by binding document stylesheets. (classify as a SHOULD?)
  5. XBL2: Provide an option that allows shadow tree elements to be styled by bound document stylesheets. (classify as a MAY?)

The next two requirements are general XBL requirements that are of relevance here:

  1. Support ability for XHTML+XForms+SVG compound document to implement XForms UI controls using either a native XForms implementation or sXBL with HTML+SVG shadow trees. This is a forward-looking requirement for the future CDI work within the Compound Document Working Group. One implementation of CDI might want to implement XForms controls as a first-class user agent feature where the XForms controls are built into the user agent, whereas another implementation might want to implement XForms controls using sXBL with shadow trees containing a combination of XHTML and SVG. In both cases, it is expected that bound document stylesheets should be able to attach CSS properties to the bound element child elements such as <xforms:label> (e.g., "xforms|label { color:blue }"). A similar requirement would be the ability to implement HTML's own form controls using SVG+sXBL (e.g., implement <html:button> using XBL with SVG shadow trees).
  2. Provide an option that allows bound element children to be styled by bound document stylesheets. This option would allow portions of an HTML user agent to be implemented using SVG+XBL and achieve the same behavior as a pure HTML user agent. For such an implementation, bound document stylesheets must be able to attach properties to the children of the bound document.

4 Proposals

4.1 Proposal 1: Universal selector matching to cater for XBL2 and sXBL use cases

4.1.1 Proposal

In short, the proposal is that selectors be matched against certain variants of the flattened tree where deeper scopes are ignored one at a time until the element is considered ignoring all deeper scopes.

In sXBL (and in XBL2 by default unless certain attributes are set), an extra condition applies, namely that only nodes in the same scope are ever considered.

The goal of this proposal is to maintain encapsulation and information hiding while not exposing XBL internals to the styling model. In addition, forwards-compatibility is ensured by defining the model in a way that handles important XBL2 use cases.

Note: The proposal below sometimes refers to possible features for XBL2. These possible features are speculative since the XBL task force has not engaged yet in rigorous discussion about XBL2.

Specifically, the definitions would be as follows.

A > B
For sXBL: Matches B if B.xblParentNode == A
For XBL2: Matches B if i: B.xblParentNodes[i] == A
A B
Matches B if B.xblParentNode == A or if B.xblParentNode == C and A C matches C.
A + B
For sXBL: Matches B if either:
For XBL2: Matches B if either:
A ~ B
Same as A + B but there may be intervening elements.

Note: This selector is not in CSS 2.0 or 2.1 but is included in the Selectors Candidate Recommendation.

In all cases, for sXBL and XBL2 (when the proposed allowSelectorsThrough attribute is false, the default), there is the additional condition that:

B.xblBoundElement == A.xblBoundElement (might be null)

This condition ensures that selectors don't cross scopes. In XBL2, the condition would be removed if an appropriate attributes were present (allowSelectorsThrough on the template elements of the shadow trees that contain B and A, for those that are in shadow trees).

In addition, pseudo-classes would be defined as follows:

In these definitions, B.xblParentNodes is the list of elements that contain content elements that acted as insertion points for B, from the nearest to the furthest (in terms of the flattened tree).

B.xblParentNode is the same as B.xblParentNodes[0].

B.xblScopedChildNodes is the list of children in what would be the flattened tree at that point if the element B had no xblShadowTree (same as childNodes if the element is from the original DOM, and same as xblChildNodes if the element isn't a bound element).

Strictly, xblScopedChildNodes would be defined as: "The xblScopedChildNodes attribute is a NodeList that represents the children of the node after content elements have been applied, ignoring the element's own shadow tree, if any. The attribute's value is the same as xblChildNodes if the node is not bound, and the same as the childNodes attribute if the element is not from a binding.

B.xblChildNodes is the list of children in the flattened tree at that point.

This proposal doesn't allow any stylesheets to apply to other scopes. For example, shadow content cannot be styled by bound document sheets, and binding document sheets cannot style bound document elements. (The only exception being the bound element, which is styled by both.) XBL2 would presumably address this using the proposed applyAuthorSheets and applyBindingSheets attributes, to allow (respectively) author sheets to apply to shadow trees, and binding sheets to apply to children of the bound element.

Examples
Example UniversalSelector-1:
   bound element:
     <theBoundElement/>


   binding template:
     <xbl:template>
       <aShadow/>
       <xbl:content/>
       <bShadow/>
     </xbl:template>


   binding document stylesheet:
     aShadow + xbl|content + bShadow { color: red; }

Using this proposal, the rule above would not match any elements in this example.

[XBL-TF open question: Should it match the element?]

Example UniversalSelector-2:
  bound element:
     <my:list>
      <html:li/>
     </my:list>


   binding template:
     <xbl:template>
      <html:ul>
       <xbl:content/>
      </html:ul>
     </xbl:template>

In XBL2, selectors like this one:

html|ul > html|li

...will need to match the above <html:li> element (for the UA stylesheet if nothing else). This proposal can be trivially extended to support this by making the "B.xblBoundElement == A.xblBoundElement" condition only be used in the sXBL model, and removing that restriction when an appropriate attribute is present.

[XBL-TF open question: The XBL task force has not engaged yet in rigorous discussion about XBL2, but at least some task force members believe that in this case html|ul > html|li should not match in XBL2 in the default case since the original content has a <my:list> element instead of an <html:ul> element, and instead only match if the binding definition says the selectors should match against the flattened tree.]

Now extend this case so that the <html:ul> element itself (in the <my:list> element's binding) is bound to:

     <xbl:template>
      <my:dummy>
       <xbl:content/>
      </my:dummy>
     </xbl:template>

In XBL2, the selector given above would still have to match. The proposal given here supports this intrinsically. It also needs to match these two selectors at the same time:

html|ul > my|dummy
my|dummy > html|li

(The first to cover cases where instead of my|dummy we're talking about another html|li, the second for the case where my|dummy is actually an html|ul.) Again, this proposal handles all this.

Example UniversalSelector-3

Here is another example which illustrates this approach:

<foo:bar>
  <svg:circle/>
</foo:bar>

<foo:bar> is the bound element with the following xblShadowTree:

<xbl:shadowTree>
  <svg:text id="t"> ... </svg:text>
  <svg:g id="g1">
    <svg:rect id="r"/>
  </svg:g>
  <svg:g id="g2">
    <xbl:content/>
  </svg:g>
</xbl:shadowTree>

Then, assuming a stylesheet in the binding document:

  1. #t — would match the 't' element
  2. svg|g > svg|rect — would match the "r" element
  3. foo|bar svg|rect — would not match — selector matching does not match across elements with different xblBoundElements in sXBL (but in XBL2, it would match if the allowSelectorsThrough attribute was set)
  4. svg|circle — would not match — selector matching does not go outside of xblShadowTree (although the same selector within a stylesheet in the bound document would match)
  5. #g2 svg|circle — would not match — selector matching does not go outside of xblShadowTree. In XBL2, the same selector within a stylesheet in the bound document would only match if the allowSelectorsThrough attribute was set.
Example UniversalSelector-4

A similar example:

<foo:bar1>
  <foo:bar2>
    <svg:circle id="c"/>
  </foo:bar2>
</foo:bar1>

Assume the bound element is <foo:bar2> and it has the following xblShadowTree:

<xbl:shadowTree>
  <svg:text id="t">
  <svg:g id="g">
    <svg:rect id="r">
  </svg:g>
  <xbl:content/>
</xbl:shadowTree>
  1. #t — would match the 't' element
  2. svg|g > svg|rect — would match the "r" element
  3. foo|bar1 svg|rect — would match "r" in XBL2, if allowSelectorsThrough is set.
  4. foo|bar2 svg|rect — would match "r" in XBL2, if allowSelectorsThrough is set.
  5. foo|bar1 > svg|g — would never match.
  6. foo|bar2 > svg|g — would match "g" in XBL2, if allowSelectorsThrough is set.
  7. svg|text + svg|g — would always match "g".
  8. svg|g + svg|circle — would match "c" in the bound document stylesheet in XBL2, if allowSelectorsThrough is set.

4.1.2 Arguments in favor

Arguments in favor of this proposal:

  1. In XBL2 we will need to be able to do cross-scope selector matching. However, XBL2 has to be a strict superset of sXBL. Therefore the selector matching model has to be compatible.
  2. This model is relatively simple given the number of use cases it handles, despite dissenting arguments to the contrary.
  3. This model is only less inefficient than CSS applied to the fully flattened tree when there are a large number of nested bindings. This is an edge case which is very likely to be only rarely seen in the real world.
  4. Cleanly supports computer science principles of encapsulation and information hiding: selectors in one scope cannot match elements in another scope, even indirectly; simple selectors in a selector chain cannot match elements that are not in the flattened tree when the selector matches an element that is in the flattened tree.
  5. Maintains backwards compatibility with existing selectors: Any CSS stylesheets already being used will continue to apply to their documents unchanged, even if bindings are introduced.

4.1.3 Arguments against

Arguments against:

  1. An implicit design criteria for W3C standards is that the processing model must be simple enough for content developers to understand. This proposal falls far short of this implicit design criteria in that it is much too complicated, even to the point of incomprehensibility. In contrast, the sXBL public draft simply said "match against fully flattened tree", which is much closer to the simplicity we need for the processing model to be readily understandable. Thus, even if this proposal were in a good general direction, it is unsuitable as described above because it is too complicated. If the binding task force believes this general direction has merit, then a simpler proposal is needed. (Note, however, that there are other arguments against this proposal beyond its complexity.) [Comment from member of XBL-TF: While the proposal does not have trivial definitions, they are not that complex. This argument against seems to me to be way too strongly worded.]
  2. The proposal is complex and inefficient to implement. In cases where scripting or animation might alter the shadow tree within a time-sensitive scenario (e.g., when requiring smooth animation), it is unacceptable if an expensive CSS cascade computation must be performed within a tight loop. The above formulas are expensive both because of all of the conditional logic and because of the "for some values of i" looping requirement. For a correct and robust implementation of SMIL Animation, the CSS cascade needs to be reapplied with each tick of the animation clock. The current definition of the CSS cascade is simple enough to allow straightforward programming optimizations; however, the above formulas are much more complex and make such programming optimizations either very difficult or potentially impossible within a compliant implementation of both XBL and SMIL Animation. (Note: SVG supports both XBL and SMIL Animation.) [Comment from member of XBL-TF: In the common case of a single binding, an in sXBL with any number of nested bindings, the proposed definitions are as efficient as a flattened tree definition (more so, in fact, since only a subset of the tree is examined). Only in XBL2, with allowSelectorsThrough set to true, and with a large number of nested bindings, does scalability suffer. Therefore I disagree that this is a disadvantage of this proposal.
  3. Example UniversalSelector-2 above depicts a use case which has <html:ul><xbl:content></html:ul> where the bound element has a child <html:li> and there is a selector html|ul > html|li. The proposal, which is already too complicated for sXBL, gains incremental complexity with the proposals for XBL2, including the additions of having to loop through multiple different traversal paths to check for matches. In contrast, the second proposal supports this use case as proposed without waiting for XBL2 and without requiring the hard-to-understand processing model, the negative performance implications, and side-effects from this proposal.
  4. Example UniversalSelector-1 above has three sibling elements <aShadow>, <xbl:content>, and <bShadow> within the shadow tree. The write-up says that the formulas will not match against the selector aShadow + xbl|content + bShadow with the comment that it makes no sense to match. However, component developers might have a good reason to do such a sibling match where one of the siblings is an <xbl:content> element. Such a sibling match makes as much sense as any sibling match -- the content creator might want the final sibling (bShadow in this case) to be styled a certain way no matter what content is referenced by the <xbl:content> element. The above proposal prevents future growth where such Core DOM traversal matching involving an <xbl:content> element would ever being allowed. This is in contrast to the second proposal below which supports both options for sibling selector matching. With the second proposal, stylingMode="domTree" supports sibling matches involving an <xbl:content> element; stylingMode="flattenedTree" supports sibling match after flattening out the <xbl:content> element; and there is a colored box which mentions a possible third option (stylingMode="importContent") for extra flexibility.
  5. The formula's complexity produces some surprising and unintuitive (and unacceptable) results in some cases. Consider the following example:
    <xbl:definition element="foo:bar">
      <xbl:template>
        <z>
          <xbl:content includes="a"/>
          <xbl:content includes="b"/>
        </z>
      </xbl:template>
    </xbl:definition>
    
    <foo:bar>
      <b/>
      <a/>
    </foo:bar>
    It appears that according to the above definitions that all of these selectors within binding document stylesheets will match (and the first two are surprising!):
    a:first-child
    a + b
    b + a
    Notes:

    Another significant and unintuitive problem: If we change the above example by adding <svg:metadata> or <smil:animate> or <html:div display="none"> as a first child of z, then no :first-child selector within a bound document stylesheet will ever match any child of <foo:bar>, which will be very surprising to the author of the bound document.

4.2 Proposal 2: 'stylingMode' and 'ownerDocument" attributes

4.2.1 Proposal

There have been justifiable requests for CSS selector matching that supports fully encapsulated components (as how things worked in RCC) and for situations where the effect of the bindings are transparent. These two approaches align with standard programming techniques where sometimes it is best to use function calls (which generally are implemented using black-box methods where the underlying implementation is unknown) and other times it is best to use macros (where the result of the macro is transparent to the code that invokes the macro). To satisfy the various requirements, this proposal suggests introducing an attribute which allows CSS selectors to work off of the Core DOM or off of the flattened DOM.

To satisfy both requirements, this proposal suggests the addition of a 'stylingMode' attribute to the <xbl:definition> element as follows:

Attribute name: stylingMode
Possible values: domTree|flattenedTree (default=domTree)

For elements that are descendants of <xbl:shadowTree> or descendants of the bound element which are the targets for <xbl:content> elements:

In many cases, the component developer wants all styling controlled by binding document stylesheets, but in other cases he wants shadow content to be "transparent" to the bound document such that bound document stylesheets can apply to elements in the shadow tree. To satisfy these requirements, this proposal suggests the addition of an 'ownerDocument' attribute to the <xbl:definition> element as follows:

Attribute name: ownerDocument
Possible values: bindingDocument|boundDocument (default=bindingDocument)

This attribute controls the value of the DOM Core "ownerDocument" property on the Node interface for the <xbl:shadowTree> element and all nodes which are cloned from the <xbl:template> element and inserted as descendants of the <xbl:shadowTree> element. Setting the DOM Core "ownerDocument" property controls which set of stylesheets are active on elements which are descendants of <xbl:shadowTree>. When ownerDocument="bindingDocument", binding document stylesheets apply to these elements. When ownerDocument="boundDocument", then bound document stylesheets apply.

Examples
Example StylingMode-1:

Here is an example which illustrates the stylingMode="domTree" approach:

<foo:bar>
  <svg:circle/>
</foo:bar>

Assume the bound element has the following xblShadowTree:

<xbl:shadowTree>
  <svg:text id="t">
  <svg:g id="g1">
    <svg:rect id="r">
  </svg:g>
  <svg:g id="g2">
    <xbl:content/>
  </svg:g>
</xbl:shadowTree>

With a value of stylingMode="domTree" on the <xbl:definition> element for the binding, the following shows how various style declarations from a binding document stylesheet match against the shadow content (assuming ownerDocument="bindingDocument"):

  1. #t -- would match the "t" element
  2. svg|g > svg|rect -- would match the "r" element
  3. foo|bar svg|rect -- would not match -- with stylingMode="domTree", selector matching does not match against elements within the bound document, including the bound element
  4. svg|circle -- would not match -- with stylingMode="domTree", selector matching does not match against elements within the bound document
  5. #g2 svg|circle -- would not match because the circle element is in the bound document
Example StylingMode-2:

Here is an example which illustrates the stylingMode="flattenedTree" approach:

<foo:bar1>
  <foo:bar2>
    <svg:circle id="c"/>
  </foo:bar2>
</foo:bar1>

Assume the bound element has the following xblShadowTree:

<xbl:shadowTree>
  <svg:text id="t">
  <svg:g id="g">
    <svg:rect id="r">
  </svg:g>
  <xbl:content/>
</xbl:shadowTree>

The fully flattened XBL topology (i.e., using xblParentNode, xblFirstChild, xblNextSibling, xblChildNodes, etc.) would be:

<foo:bar1>
  <foo:bar2>
    <svg:text id="t">
    <svg:g id="g">
      <svg:rect id="r">
    </svg:g>
    <svg:circle id="c"/>
  </foo:bar2>
</foo:bar1>

With a value of stylingMode="flattenedTree" on the <xbl:definition> element for the binding, the following shows how various style declarations from a binding document stylesheet match against the shadow content:

  1. #t -- would match the "t" element
  2. svg|g > svg|rect -- would match the "r" element
  3. foo|bar1 svg|rect -- would match the "r" element
  4. foo|bar2 svg|rect -- would match the "r" element
  5. foo|bar1 > svg|g -- would not match the "g" element because within the fully flattened XBL topology the "g" element is a grandchild of <foo:bar1>, not a child.
  6. foo|bar2 > svg|g -- would match the "g" element because within the fully flattened XBL topology the "g" element is a child of <foo:bar2>.
  7. svg|circle -- would not match because the <svg:circle> element is styled by bound document stylesheets
  8. svg|text + svg|g -- would match the "g" element
Example StylingMode-3:

The following example was copied from one of the arguments against Proposal 1. Assume the following binding definition:

<xbl:definition element="foo:bar" stylingMode="???" ownerDocument="???">
  <xbl:template>
    <z>
      <xbl:content includes="a"/>
      <xbl:content includes="b"/>
    </z>
  </xbl:template>
</xbl:definition>

And the following bound element:

<foo:bar>
  <b/>
  <a/>
</foo:bar>

And assume the following selectors:

a:first-child
a + b
b + a

The topology of the fully flattened XBL tree in this case would be:

<foo:bar>
  <z>
    <a/>
    <b/>
  </z>
</foo:bar>

Here is a table which shows the results for the possibles values of stylingMode and ownerDocument:

Selector selectors are in binding document stylesheet,
<xbl:definition> has ownerDocument="bindingDocument"
selectors are in bound document stylesheet,
<xbl:definition> has ownerDocument="boundDocument"
<xbl:definition> has stylingMode="domTree" <xbl:definition> has stylingMode="flattenedTree" <xbl:definition> has stylingMode="domTree" <xbl:definition> has stylingMode="flattenedTree"
a:first-child Would not match Would not match Would not match Would not match
a + b Would not match - b's ownerDocument is the bound document, so binding document stylesheets do not apply Would not match - b's ownerDocument is the bound document, so binding document stylesheets do not apply Would not match. Using regular DOM traversals, it is (b, a), not (a, b). Would match. b's ownerDocument is the bound doument and in fully flattened topology, xblChildNodes is (a, b).
b + a Would not match - a's ownerDocument is the bound document, so binding document stylesheets do not apply Would not match - a's ownerDocument is the bound document, so binding document stylesheets do not apply Would match. a's ownerDocument is the bound doument and in regular DOM traversals, it is (b, a). Would not match. Using flattened DOM traversals, it is (a, b), not (b, a)
z > a Would not match - a's ownerDocument is the bound document, so binding document stylesheets do not apply Would not match - a's ownerDocument is the bound document, so binding document stylesheets do not apply Would not match. In Core DOM traversals, a is not a child of z Would match. Using flattened DOM traversals, a is a child of z
foo|bar > z Would not match - Selector traversals do not cross from xblShadowTree to bound element. Would match - in flattened DOM, z is a child of foo:bar Would not match - z's ownerDocument is the binding document, so bound document stylesheets do not apply. Also, it wouldn't be possible to cross from z to foo:bar using Core DOM traversals. Would match - in flattened DOM, z is a child of foo:bar
foo|bar a Would not match - a's ownerDocument is the bound document, so binding document stylesheets do not apply Would not match - a's ownerDocument is the bound document, so binding document stylesheets do not apply Would match - Using regular DOM traversals, a is a descendant of foo:bar. Would match - in flattened DOM, a is a descendant of foo:bar.
foo|bar z a Would not match - a's ownerDocument is the bound document, so binding document stylesheets do not apply Would not match - a's ownerDocument is the bound document, so binding document stylesheets do not apply Would not match - Using regular DOM traversals, a is a direct child of foo:bar. Would match - in flattened DOM, a is a descendant of z which is a descendant of foo:bar.

4.2.2 Arguments in favor

Arguments in favor of this proposal:

  1. This proposal offers a pure DOM approach to attaching selectors, and in fact it is the default. Offering a pure DOM option is necessary for backwards-compatibility with existing W3C technologies. It's the use case for CSS1, CSS2, CSS2.1, CSS and Xpath. It's the pre-XBL status quo, the current situation. Usually, specifications that introduce a new feature allow the situation before the feature was introduced. Typically, they make the old behavior the default, too.
  2. This proposal is simple and understandable.
  3. This proposal is predictable, with no surprising side effects.
  4. This proposal offers an option for full encapsulation.
  5. This proposal offers the styling against the flattened DOM, a feature targeted for XBL2 without having to wait for XBL2.

4.2.3 Arguments against

Arguments against:

  1. The "domTree" approach doesn't have encapsulation of the shadow tree, as it exposes the shadow tree's innards (such as the content elements) to the cascade engine.
  2. The "flattenedTree" approach doesn't handle the case where you have mixed bindings -- some of which want encapsulation and some of which want to be transparent. (This is the reason for xblScopedChildNodes in the first proposal.)
  3. Neither option allows the bound document stylesheets to ever match on bound document elements based on their final position relative to shadow tree elements, which is a requirement to handle HTML UA stylesheets correctly in the face of bindings (amongst other things).
  4. The ownerDocument DOM attribute has nothing to do with styling and it seems very odd to be relating the two in this way. (Is this an implementation detail that is leaking into a spec proposal?)

5 Outside Feedback

Since neither of the proposals listed above were included in the latest public sXBL draft specification, it makes sense to wait for feedback on the above proposals before attempting to summarize public feedback on this issue.