Re: [csswg-drafts] [css-shadow-parts] Make `::slotted()` a combinator (#7922)

The CSS Working Group just discussed ``[css-shadow-parts] Make `::slotted()` a combinator``.

<details><summary>The full IRC log of that discussion</summary>
&lt;TabAtkins> lea: Right now, the syntax aorund shadow dom includes a lot of pseudos - ::part(), ::slotted()<br>
&lt;TabAtkins> lea: ::slotted() is probably the easiest to "fix". Bunch of problems with it - can't use querySelector(), can't target descendants<br>
&lt;TabAtkins> lea: I udnerstand this seems desirable to avoid breaking encapsulation.<br>
&lt;TabAtkins> lea: But so many use-cases - wrappers, etc - that need the ability to select past.<br>
&lt;TabAtkins> lea: No way to target siblings of slotted elmeents, their pseudo-elements, etc<br>
&lt;TabAtkins> q+<br>
&lt;TabAtkins> lea: I had thought this was why their styling had low specificity, but that's actually a different issue<br>
&lt;TabAtkins> lea: There's no way to detect slots that have content....<br>
&lt;emilio> q+<br>
&lt;TabAtkins> lea: if "slotted" was a combinator you could use :has()<br>
&lt;TabAtkins> lea: In general, ::slotted() seems like a wart we introduced to get things done quickly, but it causes a lot of problems<br>
&lt;TabAtkins> lea: Ultimately, the relationships between elements is what combinators are for<br>
&lt;TabAtkins> lea: Using pseudo-elements introduces a lot of problems<br>
&lt;TabAtkins> lea: It seems like turning the syntax into a combiantor would solve a lot of problems, even if we have to apply restrictions for now<br>
&lt;TabAtkins> lea: Seems better than piling on more syntax over what pseudo-elements are.<br>
&lt;TabAtkins> lea: We can add more syntax, extend definitions, etc, but ultimately what people need is a combinator.<br>
&lt;emilio> TabAtkins: I think `::part()` has still good justification for its existance<br>
&lt;emilio> ... slotted was indeed kind of a workaround<br>
&lt;emilio> ... I agree if we could do this it'd be good<br>
&lt;TabAtkins> emilio: I think the main restriction that ::slotted() being a pseudo  gets you is that arbitrary elements in the light dom can't be targeted by shadow roots<br>
&lt;TabAtkins> emilio: that's a perf consideration<br>
&lt;TabAtkins> emilio: don't wnat to have to look thru arbitrary ancestor chains to know what nodes you need to pull styles from<br>
&lt;TabAtkins> emilio: ::slotted() being a pseudo-element guarantees you that you only need to look at the shadows you're slotted to<br>
&lt;lea> q?<br>
&lt;lea> q+<br>
&lt;astearns> ack TabAtkins<br>
&lt;TabAtkins> emilio: So I think that's a strong justification. I understand the limitations tho.<br>
&lt;emilio> ack emilio<br>
&lt;astearns> ack emilio<br>
&lt;astearns> ack lea<br>
&lt;TabAtkins> lea: I understand it might be tough to do impl-wise due to assumptions made so far.<br>
&lt;TabAtkins> lea: a path forward might be to make it a very restricted combinator at first, syntactigc sugar over the pseudo-element<br>
&lt;TabAtkins> lea: whatever argument you can put inside of ::slotted(), that's all that's allowed after it<br>
&lt;emilio> q+<br>
&lt;TabAtkins> lea: authors then could migrate over to using the new syntax. the longer we wait the more existing CSS we'll have to deal with.<br>
&lt;TabAtkins> lea: so paving the way with a restricted combinator is a way forward<br>
&lt;astearns> ack emilio<br>
&lt;TabAtkins> emilio: I'd lvoe to hear other impl takes<br>
&lt;bramus> q+<br>
&lt;TabAtkins> emilio: this doesn't look like the kind of restrictions you can lift<br>
&lt;TabAtkins> emilio: to figure out how to style a node that's a descendant or sibling of something slotted, you'd need to start arbitrarily walking the ancestor chain to find your closest ancestor that might be slotted<br>
&lt;TabAtkins> emilio: not even clsoest, all of them<br>
&lt;TabAtkins> emilio: I don't think this is the kidn of restriction we can really depend on<br>
&lt;bramus> q-<br>
&lt;astearns> https://github.com/w3c/csswg-drafts/issues/7922#issuecomment-2380098440<br>
&lt;TabAtkins> TabAtkins: ryosuke had some comments<br>
&lt;bramus> scribe+<br>
&lt;bramus> TabAtkins: the usefulness of it as lea listed is taht some of other syntactic parts of css work automatically<br>
&lt;bramus> … all the pseudoe classes and elements of a slotted one would be available<br>
&lt;bramus> emilio: but those already work><br>
&lt;bramus> lea: queryselector will<br>
&lt;lea> s/ lea: queryselector will/ lea: queryselector too/<br>
&lt;bramus> tabAtkins: i dont think you can do ::slotted::before<br>
&lt;bramus> emilio: 99% sure<br>
&lt;bramus> iank_: (missed)<br>
&lt;bramus> TabAtkins: the qs() issue is rather frustrating too<br>
&lt;astearns> s/(missed)/I don’t think our style experts have seen this, but I can ping them/<br>
&lt;bramus> emilio: we would never be able to return textnodes<br>
&lt;bramus> TabAtkins: we dont<br>
&lt;bramus> emilio: (missed)<br>
&lt;lea> q?<br>
&lt;bramus> lea: i have been in csswg meetings where certain things that shipped today that the consensus was that it would never fly<br>
&lt;bramus> … there was a time where :has() was never possible<br>
&lt;bramus> … restrictions on what is impl. change over time<br>
&lt;bramus> … we should not design syntax around current limitations<br>
&lt;bramus> … we can expand it later<br>
&lt;bramus> … we did with nesting<br>
&lt;bramus> … at the time, nesting was designed without lookahead<br>
&lt;astearns> q+<br>
&lt;bramus> … and we designed a syntax that was compatible with unbounded lookahead<br>
&lt;bramus> … and eventually andruud and others had a good idea and it became possible<br>
&lt;bramus> … thats why i think to move to a syntax that would allow the expansions<br>
&lt;emilio> ::slotted() pseudos work afaict: https://www.software.hixie.ch/utilities/js/live-dom-viewer/saved/13451<br>
&lt;bramus> … (missed)<br>
&lt;bramus> s/(missed)/adding more warts of what pseudo elements were designed to do<br>
&lt;bramus> … we are using them more and more to represent elements in the DOM<br>
&lt;bramus> … its adding difficulty to learning CSS<br>
&lt;emilio> q+<br>
&lt;bramus> astearns: would push back on that. its not that we cant expand the pseudo syntax but that it would be likelye a one-off thing<br>
&lt;bramus> lea: thats what I am saying<br>
&lt;astearns> ack astearns<br>
&lt;bramus> … ideally its better solved in a way with existing things<br>
&lt;bramus> astearns: it would be still a little werid to have this combinator wher eyou might expect to be able to use it but then learn that there are limitations<br>
&lt;bramus> lea: its a tradeoff<br>
&lt;bramus> emilio: can i push back?<br>
&lt;astearns> ack emilio<br>
&lt;TabAtkins> emilio: push back on some of the things<br>
&lt;TabAtkins> emilio: it feels that turning it into a combiantor without a concrete plan to change the restrictions - it's not making CSS easier<br>
&lt;TabAtkins> emilio: If you have combiantor you can only use at very specific positions - you can't use Nesting, :has(), etc<br>
&lt;TabAtkins> emilio: so I dunno, I just don't feel like this is a meaningful improvement over the status quo<br>
&lt;TabAtkins> emilio: I get the querySelector() point. you'd need to special-case ::slotted() to return elements from another tree, currently qS() never does. But you could make it work.<br>
&lt;TabAtkins> q+<br>
&lt;TabAtkins> emilio: So I don't see this as  great answer unless there's a concrete path<br>
&lt;TabAtkins> lea: We didn't have a concrete path for nesting lookahead...<br>
&lt;TabAtkins> emilio: when we ahve a plan, we can go ahead. just don't see it useful until then.<br>
&lt;bramus> TabAtkins: looking over the list of things again, th ecurrent restrctions<br>
&lt;bramus> … some of them have been lfited, not what we can put pseudo after ::slotted is nice<br>
&lt;lea> s/We didn't have a concrete path for nesting lookahead.../We didn't have a concrete path for the north start nesting syntax either when we resolved to get partway there/<br>
&lt;bramus> … if we can fix qs to refer to slotted tha twould fix that part<br>
&lt;bramus> … the specificity one is prolly not compat when we try to fix<br>
&lt;bramus> … we still need has-slotted that you do want to know if there are text nodes in it<br>
&lt;lea> q+<br>
&lt;bramus> … if we just fix queryselector and think about specificity we might be sufficiently fine<br>
&lt;astearns> ack TabAtkins<br>
&lt;bramus> emilio: i dont see the tradeoff to making it a combinator be particularly good<br>
&lt;bramus> lea: either way we go,<br>
&lt;bramus> … if we continue pushing on the syntax we have<br>
&lt;bramus> … there is going to be at least 1 word here<br>
&lt;bramus> … not going to be elegant<br>
&lt;astearns> s/word/wart/<br>
&lt;bramus> ; if we continue pushing on the pseudo-element route, thre is multiple types of weirdness<br>
&lt;bramus> … every DOM api that takes  selector must also accept it<br>
&lt;bramus> … if authors want to provide a way for their users, they also have to special case that<br>
&lt;bramus> … and parse selectors on their won<br>
&lt;emilio> q+<br>
&lt;astearns> ack lea<br>
&lt;bramus> … yes, we can special case specificity fixing cascade order is not enough<br>
&lt;bramus> … and who knows what else to special case down the line?<br>
&lt;bramus> … adding more warts to the language<br>
&lt;bramus> … which we have to deal with forever<br>
&lt;bramus> … OTOH if we go combinator route there is only 1 word which we can get rid of later on<br>
&lt;bramus> … for me it seems that the combinator is in favor<br>
&lt;bramus> …when trying to see the big picture<br>
&lt;bramus> … but ymmv<br>
&lt;kbabbitt> s/word/wart/<br>
&lt;emilio> ack fantasai<br>
&lt;TabAtkins> fantasai: two comments. we shoudl keep in mind the experience of the author, so giving them a consistent syntax on a consistent model makes the platform more usable. that's worth doing if it's possible, it's not a no-op even if it seems that way from an engine perspective<br>
&lt;TabAtkins> fantasai: in the distant past we discussed putting elements/combiantors *after* a pseudo-element to indicate that they're processed relative to the pseudo; kinda the pseudo-element is a combinator<br>
&lt;TabAtkins> fantasai: ::region(foo) > a<br>
&lt;astearns> ack emilio<br>
&lt;lea> q+<br>
&lt;TabAtkins> emilio: I'm just not sure I agree that having a combinator ... it won't allow us to remove the pseudo, and a lot of the things you've mentioned work that way with ::slotted() already<br>
&lt;fantasai> s/::region(foo) > a/.foo::nth-fragment(2) a/<br>
&lt;TabAtkins> emilio: a bunch of special cases you need to special case *anyway* because it's a combinator and pointing to a different tree<br>
&lt;TabAtkins> emilio: I'm seeing it's two warts. You have a pseudo-element, and you have ac ombinator, and they both ahve restrictions<br>
&lt;TabAtkins> emilio: like `foo /slotted/ bar { div {...}}` needs to not work<br>
&lt;TabAtkins> lea: you need to invalidate that not at the syntax level, but at selector resolution<br>
&lt;TabAtkins> emilio: right, that's what pseudo-elements do today, it's the same restrictions<br>
&lt;lea> :host: /slotted/ .foo { &amp;.bar { } }<br>
&lt;TabAtkins> lea: that's not possible with pseudo-elements<br>
&lt;TabAtkins> emilio: that's a third new wrinkle<br>
&lt;TabAtkins> lea: not a wrinkle, it's the same as what selectors do today<br>
&lt;TabAtkins> astearns: I dont' think people will be convinced today. Take it back to issue, emilio outline problems with combinator restrictions. We can see how extending querySelector() to allow ::slotted() might look so we can balance things against the proposal.<br>
&lt;TabAtkins> emilio: lea, you asked about pseudo-elements somehow forcing people to parse selectors in content<br>
&lt;TabAtkins> lea: say you have a web component that references other elements. a tooltip for something.<br>
&lt;TabAtkins> lea: either you do IDREF like HTML, or take a selector in an attribute<br>
&lt;TabAtkins> lea: Very useful for libraries to take selectors. There's a mutationObserver wrapper that uses selectors, for instance<br>
&lt;TabAtkins> lea: If we have to special-case certain pseudo-elements, authors also have to do so<br>
&lt;TabAtkins> lea: So I think it's better to have combinators return elements<br>
&lt;TabAtkins> lea: i think it's a good design principle to strive towards<br>
&lt;TabAtkins> emilio: I can buy that. But the pseudo-element isn't going to go away, so authors will need to special-case it anyway.<br>
&lt;TabAtkins> emilio: and they'll need to special-case the /slotted/ as well due to the restrictions<br>
&lt;TabAtkins> astearns: another thing we could ahv eint he issue discussion is whether there is a feasible path to removing the restrictions<br>
&lt;TabAtkins> emilio: yeah, i'm fine *if* we ahve a path to improve this so /slotted/ is a regular combinator, I just dont' see it<br>
&lt;TabAtkins> lea: we don't have to remove all, would probably be easier to let it look into descendants than looking everywhere<br>
&lt;TabAtkins> emilio: not really, sibling would be easier i think<br>
&lt;TabAtkins> emilio: what the browser needs is, giving node X, find all the places rules styling X will come from<br>
&lt;lea> q-<br>
&lt;TabAtkins> emilio: So alan's plan seems reasonable. Figure out what restrictions could be lifted, evaluate from there.<br>
&lt;TabAtkins> astearns: If we do the combinator we dont' have to lard up the pseudo-element<br>
&lt;TabAtkins> astearns: closing this for now, discuss more in issue<br>
&lt;TabAtkins> lea: we also need to listen to the author community, this is something the WC community has been very excited about<br>
&lt;TabAtkins> emilio: I think that's mostly a misunderstanding about the combinator restrictions fixing some things<br>
&lt;TabAtkins> emilio: I think a lot of the demand is based on the combiantor allowing this to work how they want, like it's interleaved with the outer document rules. but that's not how it's going to work.<br>
&lt;TabAtkins> emilio: rules from different trees just don't interleave, they're either fully before or after<br>
&lt;TabAtkins> emilio: I do think that's osmething we want to fix, but that's a separate issue<br>
</details>


-- 
GitHub Notification of comment by css-meeting-bot
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7922#issuecomment-2623196458 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 29 January 2025 23:54:52 UTC