W3C home > Mailing lists > Public > www-style@w3.org > February 2014

Re: Shadow DOM Encapsulation

From: Peter Linss <peter.linss@hp.com>
Date: Thu, 6 Feb 2014 16:40:25 -0800
Cc: www-style list <www-style@w3.org>
Message-Id: <84FC2D81-999C-42F9-88BA-66E4F9F107D8@hp.com>
To: Tab Atkins Jr. <jackalmage@gmail.com>
Please note that this was not the only proposal, and each of the problems you point out below were addressed by my proposal.

To reiterate for the new thread, I proposed two mechanisms for exporting pieces of a shadow component. Either or both could be implemented.

The first would be to allow exporting pieces by a simple flag, rather than a part='' attribute you could simple specify <piece export>...</piece>. The piece would be exported by its tag name and the export would also apply to all nested pieces, unless there was another flag to turn it off, such as: ''no-export' (or maybe 'public' and 'private' for the attribute names). If you want to set the exported name as something other than the tag name you could specify that as export='name'. This would allow the creation of a fully public component by simply adding a single attribute to the shadow root node and addresses your problem #1.

The second proposal was to provide an optional style map for the component. We could create a simple syntax to define an arbitrary 'style node' tree and map it to component pieces via selectors. I don't have a specific syntax at hand, but if folks are interested I'm sure I could come up with something reasonable fairly quickly.

The other part of my proposal was to simply use pseudo-elements to directly select the exported component pieces by name, and to relax the restrictions on pseudo-element selectors to allow pseudo-classes, attribute selectors, and descendants (with combinators).

With those restrictions relaxed, it's not necessary to flatten the pseudo-element space, so the internal structure of exported pieces could be maintained.

So a piece could be selected as:
component ::piece { ... }
it's child could be selected as:
component ::piece ::child-peice { ... }
etc, with the full expressiveness of selectors. This addresses your points #2 & #3.

While allowing a component to simply opt-in to exposing it's internals to selectors, this also allows components to expose only a subset (or nothing). The style map solution would allow the component to describe an arbitrary structure to the selector system and map it to an arbitrary internal structure. Allowing the internals of the component to change without breaking external references.


On Feb 6, 2014, at 3:35 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:

> So, the major proposal people have in opposition to the above is to
> lock down shadow dom completely in CSS, and allow components to
> surface individual pieces via a part='' attribute.  You can then
> access those elements from the outside document via a ::part()
> pseudo-element hanging off of the component, like "x-foo::part(bar)".
> This has a few problems:
> 1. You have to explicitly tag each element that you want to surface.
> Some types of components want to expose their entire selves, because
> they're being used just as API surface, etc.  Some just want to expose
> a *lot*; they don't need to literally expose everything, but it's
> still annoying to spam a part='' attribute everywhere.
> 2. ::part effectively flattens the structure of the internals.  It's
> very similar to allowing only a simple selector on the tree, no
> combinators.  This is obviously rather limiting, for the same reasons
> it would be limiting to disallow combinators from the outside page.
> Hopefully I don't need to illustrate use-cases for combinators.  ^_^
> 3. ::part, at least as naively defined above, doesn't handle nesting
> of components, either.  This breaks down in two ways:
>  3a. If you want to style a particular component, regardless of where
> it's used in the page, you can't do it with ::part.  For example, if
> you're using the jQuery UI WC library, and you want every use of the
> <jq-button> to be styled in a particular way, you can't do it.
>  3b. When building a component, it often makes sense to factor out
> some bits into their own components.  This is just an internal detail,
> for code elegance; it shouldn't matter for the outside world.  Does
> this mean that you need some way to surface the parts of nested
> components as your parts?  Do you need to list all the exposed parts
> explicitly, or do you just send them all up by default?
> Let's be clear - these probably could be fixed. However, it would take
> quite a bit more time to develop, and "fixing" them would be done by
> relaxing the very containment that people are asking for.  By the time
> you're done, you have something almost as wide-open as ^/^^ already,
> but with a clumsier syntax.
> This is the problem with trying to address all the problems at once,
> with a single mechanism.  There are use-cases for higher restrictions,
> but there are plenty of use-cases in lots of directions for more
> general uses, too, and you can't solve all of them without losing the
> restrictiveness that the first use-cases wanted, or ending up with
> awkward and hard-to-understand syntax/data model.
> This is why we ended up with a "hidden, but open if you want" model
> for JS Shadow DOM, and why we ended up with the exact same model for
> CSS.
> ~TJ

Received on Friday, 7 February 2014 00:40:55 UTC

This archive was generated by hypermail 2.3.1 : Friday, 7 February 2014 00:40:56 UTC