Closed lukasoppermann closed 8 years ago
Hi, I hate to sound patronizing but I just wanted to make sure you know that this is an issue tracker for W3C's web components specifications. We use this issue tracker to modify and update specifications for such features as Shadow DOM and Custom Elements API. Do you have a specific issue with the spec text or a specific feature in shadow DOM? e.g. Are you suggesting that we should add the support for styling descendants of slotted elements?
If you're simply asking what would be the way to achieve what you're trying to do with the existing specifications and with shipping browsers, places like stackoverflow and polymer-dev mailing list would be a more appropriate place to post your question.
Hey @rniwa, I am aware that this is a specs repo and to my understanding this kind of styling is not supported, which leads to my complicated way of building this. (I just wanted to show a real example, which I think is not so exotic).
I am suggesting that the specs are altered in a way that would allow for all slotted elements to be styled.
Are you suggesting that we should add the support for styling descendants of slotted elements?
Exactly!
In that case, you could (separately) describe the exact regular/light DOM, shadow DOM, where exactly you're inserting a checkbox, and the desired composed tree? It's unclear from your original description what they're.
Hey @rniwa,
sure, I will try, my desired setup is like this.
<my-element>
<slot></slot>
</my-element>
Than I want to insert the following into the slot (needs to be in lightdom, due to the form picking it up):
<label>
<input type="checkbox" />
<div class="material-toggle__switch">
<div class="material-toggle__knob" draggable="true"></div>
</div>
<div class="material-toggle__label">Custom Label</div>
</label>
Now I want to be able to do stuff like this within the custom elements <style>
:
::slotted(input[checked] ~ .material-toggle__switch){
/* style the .material-toggle__switch when the checkbox is checked */
}
Does this make sense to you? Do you need any more explanation/info?
That is by design. See https://github.com/w3c/webcomponents/issues/331 for details.
We don't have a plan to support an arbitrary selector for ::slotted
.
Note that we supported an arbitrary selector in ::content
(in Shadow DOM v0) in Blink, as you are suggesting, however, we had experienced that it would make the implementation complicated and would be the root cause of a performance issue. Thus, we introduced this limitation to ::slotted
intentionally.
Note that we supported an arbitrary selector in ::content (in Shadow DOM v0) in Blink, as you are suggesting, however, we had experienced that it would make the implementation complicated and would be the root cause of a performance issue. Thus, we introduced this limitation to ::slotted intentionally.
This also feels like it would break encapsulation a bit too much. For example, if you were able to provide a deep selector for slotted elements, it would touch all descendants of all slotted nodes. Besides the performance implications, this feels like a double standard: nothing can reach in, but the shadow root can reach out.
@lukasoppermann since it's light DOM, couldn't you instead do this from outside the shadow root:
my-element input[checked] ~ .material-toggle__switch
I need to check the spec, but :host
instead of my-element
might work. I'll update with my finding.
UPDATE
:host
doesn't work (I expected that but wasn't 100% sure). That said, the initial suggestion does work: http://codepen.io/treshugart/pen/pEGaVv.
Since this isn't ideal, as it would have to be added globally and for each shadow root my-element
is used in, it might be worth making your <label>
light DOM into a component that contains the checked
styles (you should probably also use :checked
instead of [checked]
). You mentioned that you can't do this because the checkbox needs to participate in the containing <form>
but we've found a workaround: in your component, mutate the host element instead of the shadow root. This makes your component content light DOM, thus able to participate in the containing form.
Maybe something like this pen will work for you?
Happy for you to ping me directly (@treshugart on twitter) since this seems out of scope for this issue thread now.
Okay, I understand the issue. I just hope for the specs to include a way to pass values to a <form>
which will solve all my issues.
@treshugart thanks, I wrote you on twitter, I don't really understand what this means:
in your component, mutate the host element instead of the shadow root. This makes your component content light DOM, thus able to participate in the containing form.
So maybe you can explain it, so I can see if it is a solution for my problem, that would be awesome.
See https://github.com/w3c/webcomponents/issues/187 for a v2 API to integrate custom elements into forms.
I know this an old thread but i was wondering if it could be reconsidered for this use case.
I have a menu with submenus and I want the html to be like this :
<ds-menu>
<ul>
<li><a href="#0">lorem ipsum</a></li>
<li><a href="#0">lorem ipsum</a></li>
<li>
<a href="#0">menu with sub menu</a>
<ul>
<li><a href="#0">sub menu</a></li>
</ul>
</li>
<li><a href="#0">lorem ipsum</a></li>
<li><a href="#0">lorem ipsum</a></li>
</ul>
</ds-menu>
I want to be able to style the submenu like this :
::slotted(ul ul a) {
color:red;
}
This is from a frontend framework I am building so I don't have access to the data various teams could be using to build it. So I rather they put the content in the slot (which is SEO friendly with bing), but i cannot access the elements that are nested in.
The only solution I have is to do something like this :
<ds-menu role="list">
<ds-menuli role="listitem"><a href="#0">lorem ipsum</a></ds-menuli>
<ds-menuli role="listitem"><a href="#0">lorem ipsum</a></ds-menuli>
<ds-menuli role="listitem">
<a href="#0">menu with sub menu</a>
<ds-menu role="list">
<ds-menuli role="listitem"><a href="#0">sub menu</a></ds-menuli>
</ds-menu>
</ds-menuli>
<ds-menuli role="listitem"><a href="#0">lorem ipsum</a></ds-menuli>
<ds-menuli role="listitem"><a href="#0">lorem ipsum</a></ds-menuli>
</ds-menu>
with roles to emulate a list for NVDA, JAWS, Voiceover, etc. Is that solution is considered good practice? I need it to work SEO and be accessible at the same time.
I am sorry if this is not the best place to ask, if anyone can point me in the right direction if this is not the right forum, please do not hesitate.
Ideally I would like to use the html tags that are meant for list and not emulate them with roles.
Hey,
as it is explained here: https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom#stylinglightdom you can only select a direct item within the
slot
.So if this is in our
slot
There is no way of styling
.company
. I understand that the idea is that slotted content may be anything and is added by the user and this should be styled by the user.However, I am running into issues with this. I am adding stuff to the slot from within my
connectedCallback
because I am building form elements. This means I need to add a checkbox into the slot so its in the same dom as the form in which the user puts this element.My desired html would be like this:
However I want to style
.material-toggle__switch
and.material-toggle__knob
depending on the:checked
state f the input. This is not possible aslabel
is the only element I can reach with::slotted
.The only solution is to listen for a
change
event and add an active class to.material-toggle__switch
with this html:While it works, it feels very inconvenient. Am I doing it wrong, or is there a way to improve this?