See
https://github.com/w3c/webcomponents/commit/9b65780f9256f26cfa531832c5a0ca5ec2d999a5#commitcomment-11603549 for the context.
I'm thinking that the _white list_ might be better than the black list for v1, given that, in practical, there are a limited number of HTML Elements for which createShadowRoot() makes sense.
The white list would be:
div, body, p, span and so on.
Please ignore my previous comment. Though I'm still wondering what is the best for v1, I'm going to enumerate the elements as the _black list_, as we planned.
Would the white list's "and so on" include things like Would that blacklist include things like input?input? I'm interested in using shadow roots on those elements.
edit: oops, I didn't ignore that comment.
Yes, I'm going to include <input> in the blacklist.
FYI. Blink supported createdShadowRoot() for <input>, however, we found that it would be hard to deliver the meaningful behavior to the users in such a case.
As of now, it doesn't make much sense to add a shadow root to <input> elements, AFAIK.
Hm, doesn't such hard-coded lists prevent innovation? I thought that the whole idea of web components is that developers can come up with new ideas and implement them without having to get browsers to adopt/change anything. With a hard-coded list you are preventing this. One now cannot enable createdShadowRoot on any element they would want/need, or for example, on all DOM elements?
I agree, however, it would be better to disable the support for these elements until we have a clear idea how the behavior should be for these elements.
AFAIR, one of the original motivations of this restriction is to achieve the interoperability.
That is interesting, because one of popular Shadow DOM tutorials use createShadowRoot on a now blacklisted element:
var host = document.querySelector('button');
var root = host.createShadowRoot();
root.textContent = 'こんにちは、影の世界!';
And one more tutorial using input. I think there are already existing use cases shown.
@mitar yep. But those only work in Chrome. When trying to create a spec that works for multiple browsers, we realized that it's not possible to specify something interoperable (for now at least). Thus this change.
It's not about use cases, it's about not knowing what it means.
I'm not sure I follow what the behavioral problem is with supporting createShadowRoot on the black-listed elements. Care to enumerate? Don't you simply loose interactivity + rendering?
It's not about use cases, it's about not knowing what it means.
What it means in Chrome then? :-)
@travisleithead well for one it depends if user agents use shadow trees to implement those elements. And I think also currently it depends on inherited shadow trees, which we removed for v1. Do you have some kind of working prototype how this would work?
No prototype yet, but just thinking about what the user-expectation would be. Obviously native rendering would be hidden, but would event handlers still trigger behavior on the element? e.g., bubbling/capture of click event, would it trigger file-upload dialog? I think the expectations would be not to have those native behaviors get triggered.
FYI.
In blink, <input> uses an user-agent shadow tree and it supports createShadowRoot(), however, we found that it would be hard to deliver the meaningful result when the user adds an insertion point, <content> (or <shadow>), in the created author shadow root. As a result, we gave up distributing the contents of a user agent shadow tree into the insertion point.
That means createShadowRoot() _works_ for <input>, but it wouldn't meet the user-expectation, as of now, unfortunately. :(
AFAIR, <img> or <iframe> would be more painful to have a well-defined behavior. We had tried to support these elements, but we decided to suspend the work in blink.
@travisleithead until you have defined that processing model, and patched these existing elements in the specification to be aware of shadow DOM and what it means for their processing model, I think supporting anything here is a non-starter.
Hm, what about then providing a blacklist of elements which cannot support insertion points?
This is what was committed here.
What about extending and then styling input?
It is fine to extend it without Shadow DOM support, but this automatically means that styling also is not possible directly.
Styling of form controls is still a largely unsolved problem. We need someone capable with a sponsor of sorts to sort through that.
I don't think we should have a fixed list of elements as the normative text as we might be adding more elements in the future. I think it's better for the normative text to refer to the binding property and then add a non-normative text enumerating the currently known list of elements with the binding property.
We should just revive the list once we add a new element like that. Alternatively we say in HTML that these elements set some kind of flag that this algorithm uses, but that seems more involved.
@annevk it turns out HTML kind of does set a flag, but it sets it in a strange way, by in the UA stylesheets section saying that elements have a binding CSS property (like binding: button;): https://html.spec.whatwg.org/#bindings
This is all done in terms of a not-implemented spec, http://www.w3.org/TR/becss/.
This seems pretty weird and maybe something that should be fixed in HTML to go with a more flag-like approach...
Right, I don't think we should depend on the rendering section. That seems very sketchy.
Sure, adding some spec-level flag in HTML makes sense to me.
I've renamed this issue.
Please see https://github.com/w3c/webcomponents/issues/312 also, which was merged to this issue.
Here are my points on #312:
It seems that the behavior of attaching shadow roots on replaced elements such as img, embed, object, etc... are not well defined. We should probably disallow it in v1.
summary element also seems to create a user-agent shadow root in Blink and WebKit as well.
In addition, we may want to consider disallowing them on SVG tref and use elements. In fact, we may want to consider allowing attachShadow only on HTMLElement and its subclasses.
See the discussion, #327.
How about having a whitelist as I thought in https://github.com/w3c/webcomponents/issues/110#issuecomment-111983764? Can we agree on having a whitelist?
If we can agree on that, let's enumerate elements which should be in the whitelist.
Whitelist seems like a sane start. Clearly any custom element (probably any HTMLUnknownElement with - in its name) should be allowed.
I was gonna say we should allow it on span and div but any custom element can be morphed into span/div by simply setting display property so it's not strictly required.
Yeah, I am thinking of span, div and any custom elements. That sounds a reasonable set as the first step.
We can expand the whitelist anytime later if required.
Do we really need span and div though? It seems like forcing the use of unknown elements / custom elements is okay. I don't want to make span and div more powerful than other elements because then everyone may start using them everywhere.
I see. It might sound _ugly_ in theory, however, giving div and span a power isn't a bad idea in practical because it's handy. I'd like to hear opinions widely about this.
I don't know what you mean by "handy". There is nothing special about div and span compared to unknown elements except that div and span will have a different interface name and they have default style rules for display.
We don't want to encourage authors to start writing pages with a bunch of div's and span's just in the case they may want to later attach shadow DOM on those elements.
I think on more elements you allow, better it is. :-) Because there are also other ways to use Shadow DOM than just for rendering purposes. For example: http://elaineshi.com/docs/shadowcrypt.pdf
I really think that Shadow DOM can open new types of web innovation, which can speed up experimentation before standardization, and limiting things to a narrow set of elements also prevents such innovation.
But from practical perspective it is useless. div and span have nothing special in them (no features, no semantic), so there is no real benefit to extend them or have Shadow DOM in them for other reasons.
What I really worry about is inability to style elements that extends build-in elements.
For instance, currently I have input[is=cs-input-text] and progress[is=cs-progress] elements that have some advanced features I need and expose some CSS variables/mixins. I do not need real Shadow Root, what I really need is just styling. Currently I achieved this with html /deep/ input[is=cs-input-text], but since this is deprecated already I do not see any replacement, which is very sad (I do not want to re-implement all semantic and accessibility features of mentioned and some other elements).
@rniwa Yeah, I understand your concerns totally. The point is, however, I guess there is a different opinion from practical perspective because I've seen several use cases of Shadow DOM other than that.
I'd like to wait for feedback from others because I think this is a very important decision.
BTW, "custom elements" include elements which extend existing ones,
like <button is="my-button">?
BTW, I have also button[is=cs-button] element which also exposes some styling via CSS variables/mixins, supports extended features (like icon attribute) that require creating Shadow Root on it.
So generally, it would be great to allow it for any elements that do not have any user agent Shadow DOM currently.
Number of elements with user agent Shadow Root seems to be much smaller, so black list is a good way too. If new elements are added to specs - they can be either completely hackable with easily accessible and standardized Shadow Root or added to updated black list, whatever makes more sense.
@TakayoshiKochi we haven't really made a decision on is="" one way or another.
@rniwa it seems there's a large number of HTML elements it would be totally fine to use shadow DOM on. <h1> and friends, <section> and friends, <var> and friends, <blockquote>, <div>, <span>... It makes sense to avoid controls for now and anything with somewhat weird semantics (e.g., <template>), but in general I think we should allow it.
@annevk I am aware of it, but my point is that if you can attach shadow on an extended
element (e.g. <button is="my-button">), it spoils the idea of whitelisting, and gives users
weird workaround to attach shadow on non-whitelisted element.
We should not be treating is attribute differently to determine whether an element can have an author defined shadow root or not.
@rniwa agreed.
Ah yes, if we do decide to include is="", it being present should indeed not suddenly allow you to attach a shadow DOM there if that was disallowed otherwise.
I'd like to move this issue forward.
As the first step, can we agree on having a white list? It seems the safest approach to me.
The initial white list might be:
divspanWe can expand this white list anytime if we can agree on adding an element to the list when such a request is coming. If we find that having a white list is hard to maintain, we can switch to a _black list_ in the future.
A whitelist is a safe approach, but from reading this thread it would seem the only elements that _really_ need blacklisting are those that don't allow html / text content.
I've many times created custom buttons where I'm projecting content into them, even if it's only text-content. I've avoided using is="" in the past because of the contention. The only other option is to create a custom element that renders a button and project the content of the custom element into the button. Even so, there are compound components where extending a single element doesn't make sense like an input + button search component.
What about blacklisting void elements and allowing everything else?
@treshugart that does not work, e.g., <iframe> was already mentioned as something we cannot allow this on.
@hayatoito why can we not include more elements we know are not problematic as I suggested in https://github.com/w3c/webcomponents/issues/110#issuecomment-148634611? I guess I don't feel particularly strongly though.
Also, we should use safelist/blocklist rather than whitelist/blacklist I think. See https://github.com/whatwg/html/issues/265 for rationale.
I was thinking about another approach. It is a bit tricky to explain, but more flexible.
What if we support Shadow Root creation on all elements, but with blocklist which contains elements that might not change their _internal structure_. What I mean is that for elements like input or progress we will be able to add Shadow Root and place some styling inside in order to create custom-looking input[is] or progress[is], but eventually it will not affect how they are constructed in terms of current internal pseudo-elements (I mean ::-webkit-progress-bar, ::-webkit-progress-value and others).
This is a bit tricky, but spec already contains similar tricks like self-closing HTML tags which are basically list of those special elements and everything else works by general rules. It would be really sad if styling postponed to v2 of this spec.
I've updated the spec, with a warning -"The list is possible to change", with a link to this issue.
https://github.com/w3c/webcomponents/commit/ada4804e979685eb00ee00274a13b395e210245c
@annevk , yeah, I've added some elements to the white list.
To be honest, I can not explain the rationale for this list fully yet. Please consider this commit just as _the first draft_.
@nazar-pc if it doesn't affect how they are constructed, it will not affect rendering either. That is somewhat closely intertwined.
@hayatoito this seems good to me (modulo comments I made on the commit). We should probably just ask for new issues if folks want to expand the safelist.
@annevk, then suggestion is something like:
Shadow Root in following elements _list_of_elements_here_ MUST contain
<shadow></shadow>(or whatever is currently in spec) in the root and MAY contain any number of<style>...</style>elements for styling purposes, any other elements are NOT allowed.
I'm really trying to find replacement for /deep/ that is used currently for this purpose.
We should probably just ask for new issues if folks want to expand the safelist.
I see. Let me close this issue. Please feel free to file a new issue if folks want to expand the safelist.
I will remove the warning message in the spec if I can feel the spec is stable enough.
Also, we should use safelist/blocklist rather than whitelist/blacklist I think. See whatwg/html#265 for rationale.
Ops. I forgot to use safelist/blocklist in the commit message. My bad. Let me use safelist/blocklist from the next.
Given that the list of HTML elements is finite, a safelist vs. a blocklist is equivalent except for future changes to HTML. I would assume any future changes to HTML would coordinate with the shadow DOM spec, especially if we take the approach in https://github.com/whatwg/html/pull/131 (or the safelist equivalent). So I think debating safelist vs. blocklist is not interesting. You should just come up with the list, in either form :).
EDIT: I see I didn't quite read to the bottom, please ignore my last sentence.
If I understand correctly the specs, I won't be able to attach shadow root to any standard SVG element and if I attach it to a custom element in SVG namespace then it won't be rendered on the screen anyway?
How Web Components are supposed to be useful with SVG given those limitations? You should at least allow attachShadow() on <g> elements or you should make custom elements in SVG namespace renderable.
As things stand, WebKit's implementation is not going to even define a custom SVG element in v1 (we'll only support direct inheritance from HTMLElement and other custom elements). We're taking baby steps and ensuring interoperable behavior across browsers instead of trying to address all uses cases in v1.
I have created a customized built-in map element, and I am continuously working to improve it and make it productions ready. It would be a major setback, I think, if the map element was not allowed to have a shadow root.
What about the main element ? It's an element similar to header, article... but it's missing in the current spec white list.
@cyrilletuzi could you file a new issue for that please?
Is there by any chance a list with the disallowed elements and the reason for why they cannot hold a shadow tree? I understand that some elements already have browsers populate a shadow tree in them or they aren’t meant to have child content at all (e.g. input).
I’m particularly interested in why the details element is not allowed.
Edit: Just found this comment among the collapsed ones:
summaryelement also seems to create a user-agent shadow root in Blink and WebKit as well.
details element has a user-agent shadow root in Blink and WebKit.
Why should it matter if UAs implement some elements using shadow DOM internally? It seems that should be an implementation detail not exposed in specs.
Why should it matter if UAs implement some elements using shadow DOM internally? It seems that should be an implementation detail not exposed in specs.
In theory, yes, in practice no. The fact these elements are implemented using shadow DOM would mean that we'd have to define exactly what happens when an author defined shadow root is attached, and we've never successfully done that. Furthermore, this poses a serious implementation challenge since having multiple shadow root isn't a thing in v1 API and its implementation. Supporting multiple generations of shadow roots in v0 had a huge implementation cost.
If and when a sensible proposal is made for defining what it means for these elements to have a shadow root, we can revisit this decision.
The fact these elements are implemented using shadow DOM would mean that we'd have to define exactly what happens when an author defined shadow root is attached
I imagined those UAs would be required to behave the same way as those which chose a different implementation strategy, not involving shadow DOM. Or is it a future compatibility concern whereby the UA's shadow tree in v2 would be somewhat exposed for integration with author's shadow trees? (Then it makes sense what I've recently read in some draft I cannot find, that using shadow DOM for implementing some elements is the default and some slots must be exposed even if an UA doesn't use shadow DOM internally – it must behave as if it did.)
The problem is defining what way they would have to behave. These elements are poorly understood standards-wise to begin with.
Most helpful comment
If I understand correctly the specs, I won't be able to attach shadow root to any standard SVG element and if I attach it to a custom element in SVG namespace then it won't be rendered on the screen anyway?
How Web Components are supposed to be useful with SVG given those limitations? You should at least allow attachShadow() on
<g>elements or you should make custom elements in SVG namespace renderable.