Re: [webcomponents] Making the shadow root an Element

On Mon, Feb 11, 2013 at 3:49 PM, Tab Atkins Jr. <> wrote:
> Right now, the shadow root inside a component isn't an element, so it
> can't host styles, etc.  This makes a few things weird, though.
> For example, it means that it's non-trivial to get at the style of
> text nodes directly inside the shadow.  Normally you can just look at
> the parentNode of a text node, but here you have to actually look at
> the host element.  And if the host element has blocked inheritance,
> you can't even do that - you have to calculate the initial value for
> yourself, because there's nothing you can actually *ask* for the style
> information.
> For another example, it means that you can't do any
> inheritance-blocking yourself, without inserting an additional
> wrapper.  If you let author inheritance through, but you want to block
> specific properties, you'd want to set "property-in-question:
> default;" at the "root" of the shadow, so it'll reset to its normal
> value.  Alternately, if we implement inheritance-blocking with CSS's
> new 'all' property
> <>, we need to set
> it on some "root", but that doesn't yet exist.
> I propose that we reify the shadow root into an element, but default
> it to "display: contents;"
> <> in the UA
> stylesheet. That way it has no layout effect by default, but provides
> a handy element for doing all the things I've talked about in this
> email.
> I haven't thought through all the implications so far, though, like
> what the element name is, if it can have attributes set on it, etc.
> Thoughts?

I chatted with Blake about this today and had some thoughts.

There is definitely no simple answer here, feels like using either an
Element or a DocumentFragment has some crappy behavior. So it's a
matter of choosing the less crappy option.

Pros of using a DocumentFragment:
* Neatly solves the problem of what to do if someone attempts to
insert the shadow root as a child somewhere. If the root is an Element
we have to choose between the Element suddenly no longer being a
shadow root, or throwing.
* Avoids the problem of what to do if someone sets a style attribute
on the shadow root, or otherwise attempts to style it. Currently the
shadow root doesn't appear in the flattened tree (though we could
maybe change that) which means that it can't be styled. This is
intuitive if the shadow root is a DocumentFragment but not so much if
it is an Element.

Pros of using an Element:
* Does mean that a lot of code which is used to dealing with just
Elements and Text nodes will "just work". For example jQuery code
freaked out [1] over hitting a node that wasn't an Element but still
had an innerHTML property. There will likely be other code that does
the same.
* Means that you can set attributes on the shadow root. Again, this is
likely something libraries will do as they walk around in subtrees.
Especially if they weren't written with the existence of shadow trees
in mind (i.e. all the time).
* More consistent with the current types of Nodes that exist.
Currently people expect all Text, Comment and DocumentFragments to
have the same API, while Elements have different APIs depending on
their name. (Documents are somewhere in between as we try to move them
to the first category, PIs and DocTypes can be ignored for most
intents). Adding API to *some* DocumentFragment will likely mean that
people will need to check just what type of DocumentFragment they
have. Again, see [1] for an example, there will be more as time


Note that the styling issue can be resolved either way. We could make
the shadow root an Element and insert it into the flattened tree, with
the default display-box value being "children". Or we could keep the
shadow root as a DocumentFragment and add a pseduo element like
::shadow-root, which lives between an element and its shadow contents.

/ Jonas

Received on Friday, 15 February 2013 07:13:26 UTC