Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

::slotted() should full support complex selector!! #745

Closed
minzojian opened this issue Mar 8, 2018 · 19 comments
Closed

::slotted() should full support complex selector!! #745

minzojian opened this issue Mar 8, 2018 · 19 comments

Comments

@minzojian
Copy link

minzojian commented Mar 8, 2018

i wrote a demo here

for good to SEO,we need support a clear dom structure in html, eg. there is a navbar component,and i add some links inside,and planning to inject them into a navbar component. (even it is not for good to SEO, as a common reuseable component, elements should be inject outside freely)

  <my-navbar>
    <ul>
      <li>link1</li>
      <li>link2</li>
      <li>link3</li>
      </ul>
  </my-navbar>

however when i try to add some style for the < li > tag inside my navbar, it just not work
i found a explanation that slotted is just use simple selector
i wonder why the ::slotted selector can't support the complex selector (or child selector)?
::slotted() should full support complex selector
it just lame if not support

@emilio
Copy link

emilio commented Mar 8, 2018

You should probably file this issue against https://github.com/w3c/csswg-drafts/. But some reasons:

  • Something like ::sloted(ul > li) doesn't make sense, because the li, which is what you'd end up selecting, is not slotted.
  • ::slotted(ul) > li, while reasonable, would slow down stuff, I'd think.

You can probably use custom properties on the <ul> and inheritance to style the <li>.

@minzojian
Copy link
Author

::slotted(ul) > li
is not work either :(

@minzojian minzojian changed the title ::slotted() shoud full support complex selector!! ::slotted() should full support complex selector!! Mar 8, 2018
@emilio
Copy link

emilio commented Mar 8, 2018

Sure, I'm just saying that if it worked, everything would become slower.

@hayatoito
Copy link
Contributor

This restriction was intentionally introduced from the beginning. See #331

@minzojian
Copy link
Author

minzojian commented Mar 8, 2018

saw that post before. but i don't know.dose that post solved the problem i faced?
i want the style of the ground children inside a slot can be define in the host component @hayatoito

@hayatoito
Copy link
Contributor

hayatoito commented Mar 8, 2018

Unfortunately, there is no way. We are unlikely to change the behavior of "::slotted" because we intentionally dropped the support of arbitrary selector for the performance reason. I hope you can find a workaround.

@minzojian
Copy link
Author

minzojian commented Mar 9, 2018

very dispoint to hear that :(
if a component can support content inject via slot, however, you just can not define the style of the specific content inside that component directly. it is not cool really.

performance or functional, i prefer to first make it functional, then we talk the performance, otherwise, it is just a disability component

if there is no directly way, i have to chose

  1. define the style inside the injected content
<my-navbar>
<style>ul li {color:red}</style>
    <ul>
      <li>link1</li>
      <li>link2</li>
      <li>link3</li>
      </ul>
  </my-navbar>

if i use multi times of the component, means i should add that style defination each time, even that style is fixed, and should be placed in a fixed place (just inside the component). it is just a page size waste of the page which use component

  1. just forget the slot function. forget the content inject like a normal component should support
    in that case, i move the inject directly into the component's render function
    however, if the inject content is different, means i should create different component. then my-navbar1,my-navbar2,mynavabar-forhome,mynavabar-forotherpage... will come out, that is just ungainly
    it is not possible if i want write a common UI library in that case

there should be a way to support inject content style defination gracefully! @hayatoito

@TakayoshiKochi
Copy link
Member

It is not easy to always make any functional thing performant.
A bit of history, we had a /deep/ combinator which was a very convenient, functional thing which suffered from scalability.
We want to take care of performance when we introduce anything in the standards.

@hayatoito
Copy link
Contributor

hayatoito commented Mar 9, 2018

performance or functional, i prefer to first make it functional, then we talk the performance, otherwise, it is just a disability component

Thanks. Let me explain a brief history.
In Shadow DOM v0 era, we had a similar pseudo element "::content(selector)", where we support arbitrary selector. We preferred to make it functional. :)

However, it turned out that supporting arbitrary selector was the cause of performance issue here, we decided to introduce a new pseudo element, "::slotted()", for Shadow DOM v1, where we banned arbitrary selector. We learned and don't want to make it wrong again.

@minzojian
Copy link
Author

@TakayoshiKochi @hayatoito
thanks for you guys' feedback
and yes the balance is hard to keep. i understand
anyway, is there any advice for my case? i think it is a typical case when we consider about a GENUINE component usage.
i really don't wanna chose any one of my 2 solutions above, that's just too ugly :(

@rniwa
Copy link
Collaborator

rniwa commented Mar 9, 2018

One solution here is to add the support for selection those 'li' elements directly your shadow tree's slot element using the imperative API: whatwg/html#3534

@minzojian
Copy link
Author

minzojian commented Mar 9, 2018

hi @rniwa
https://codepen.io/minzojian/pen/XEWoJY
i try to use manunal slotting and the slot.assign() API, but it just said that
Uncaught TypeError: this.slot1.assign is not a function
did i missed something?

oh... so it is just a proposal so far...

@rniwa
Copy link
Collaborator

rniwa commented Mar 9, 2018

There is no such an API right now. The issue 3534 in the HTML repo is where we're discussing this new API.

@TakayoshiKochi
Copy link
Member

TakayoshiKochi commented Mar 10, 2018

Another solution would be you create components instead of using <ul> (and <li>?) and
nest them so that you only have to style the directly slotted children via ::slotted().

@minzojian
Copy link
Author

i give up my component's universality and chose creating different component
navbar-home, navbar-sub-domain,navbar-app....
even they have same structures inside
:(

@minzojian
Copy link
Author

well i found a indirect solution
that is i just manual append the outside dom inside the slot, check this codepen
https://codepen.io/minzojian/pen/RMWzxj
you can see the style that defined inside of the component just worked
however, it is not work for the dom that has not defined the slot property, even not displayed
i don't know what's going on :o

@ghost
Copy link

ghost commented May 22, 2020

This restriction was intentionally introduced from the beginning. See #331

That is absolutely not a solving! Even less mean that the first idea was a good one. We need that!

@trusktr
Copy link
Contributor

trusktr commented Aug 5, 2020

  • ::slotted(ul) > li, while reasonable, would slow down stuff, I'd think.

@emilio How much slower? Is there data recorded somewhere? It would be very helpful and appreciated if browser authors would show data along with these performance hypotheses, rather than throwing out ideas with no visible and useful performance data.

End users have already outlined the use cases.


As an example, SVG may not be suitable for first-person shooter graphics, but SVG is certainly useful for other use cases within its performance constraints.

In that same light, the usefulness of ::slotted(.foo) > .bar far-outweighs (in my opinion) the performance cost for the vast majority of use cases.

Web developers should re-running any selectors unnecessarily, for example avoid running them in an animation frame loop over and over (unless that perf hit has no impact on the final outcome).

The browser can also cache results for the CSS engine and only invalidate on DOM changes (and users should definitely avoid relying on DOM tree structure changes for animation purposes, but again it really depends on the use case and even the slowest DOM manipulation can be fast enough for many cases).

@emilio
Copy link

emilio commented Aug 5, 2020

#889 (comment) has the implications. The issue is that allowing that affects not the performance of ::slotted() or slotted elements but the performance of styling all elements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants
@hayatoito @rniwa @trusktr @minzojian @emilio @TakayoshiKochi and others