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

[css] add support for ::slotted selectors #58

Closed
caridy opened this issue Feb 4, 2018 · 12 comments
Closed

[css] add support for ::slotted selectors #58

caridy opened this issue Feb 4, 2018 · 12 comments
Labels
standards-gap This represents any work that is currently in the Web Component standard but is not in LWC Synthetic Shadow Synthetic shadow DOM polyfill
Milestone

Comments

@caridy
Copy link
Contributor

caridy commented Feb 4, 2018

There are few issues with ::slotted that we should take into consideration, more details here: WICG/webcomponents#728

@caridy caridy added this to the 220 milestone Jan 26, 2019
@caridy
Copy link
Contributor Author

caridy commented Jan 26, 2019

We need a volunteer to work on this. My mental model is easy, we can have a custom attribute for when the slot is supposed to display slotted content, and in that case, we do:

::slotted(input){
  color: red;
}

compiled into:

::slotted(input),
[c-foo_foo]>input {
  color: red;
}

That seems good enough, and should work fine in both cases, synthetic and native. @pmdartus what do you think?

@pmdartus
Copy link
Member

I think the hardest part here is the replicate the fact that the ::slotted() pseudo-element should be applied after the flattening.

Here is a complex example: https://jsfiddle.net/wLmbq354/1/

<x-parent>
	#shadow
	|	<style> ::slotted(div) { color: red; } </style>
	|	<x-child>
	| 		#shadow
	|		|	<style> ::slotted(*) { color: blue; } </style>	
	|		|	<slot name="slot3">
	|		<slot name="slot2" slot="slot3">
	|			<slot name="slot1">
	<div slot="slot1">
	<span slot="slot1">

As far as I understand the specification, the pseudo-selector should be applied to the elements that are returned by slot.assignedElements({ flatten: true }). So if you invoke it on slot2 and slot3 it should return the div and the span.

Before discussing how this will be implemented in LWC, I just want to make sure we got this right. It appears that Webkit is the only engine implementing the spec properly:

  • Webkit: div is red and span is blue
  • Blink and Gecko: div is red and span is black (the tree is not properly flattened)

@caridy Can you confirm we have the same understanding of the spec here so I can open bugs on respective engines?

That being said, I don't think the [c-foo_foo] > input will make the cut if we want to support flattening properly. I think we will need to add another attribute for slotted content, but I think it will be tricky to get that right.

@caridy
Copy link
Contributor Author

caridy commented Feb 19, 2019

I don't fully understand the issue, let's chat about it.

@Templarian
Copy link
Contributor

@pmdartus Looked around to see if Chrome had any open bugs and I don't see anything resembling this in the tracker. I think I understand the bug.

@caridy Not sure how far this conversation went, but assuming no complex nesting would it be possible to implement a restricted ::slotted support.

::slotted(div) { }
::slotted(div:hover) { }
::slotted(div:hover)::before { }

Seeing as it translates to specific styles for legacy the performance issue seems minimal.

@caridy
Copy link
Contributor Author

caridy commented Sep 20, 2019

I don't remember the offline conversation about this... maybe @pmdartus remembers it. we can always chat again :)

@pmdartus
Copy link
Member

No, I don't recall having this conversation.

@Templarian If we are able to implement the ::slotted selector properly I don't see any blocker handling complex compound selectors. I don't see any issue make those selector work once we agree on how the trees should be flattened.

@gregwhitworth
Copy link

@pmdartus any update on the interop issue that caused the blocking of implementing this as I just discussed utilization of this psuedo and wasn't aware that we didn't allow it. Do you have a repro testcase to test the interop and if it does exist we can get this fixed in engines that are blocking our implementation.

@pmdartus
Copy link
Member

The repro can be found in the original post. The issue is still reproducible today.

@gregwhitworth Before opening a bug against a specific engine, I would like to understand which engine is wrong. TBH, this issue is reaching the limits of my understanding of the CSS spec. Do you know someone that might help?

@gregwhitworth
Copy link

This actually doesn't have to do with CSS itself, but the implementation or interpretation of this specific aspect of the HTML specification. Specifically stating:

The ::slotted() pseudo-element represents the elements assigned, after flattening, to a slot.

So basically, when you follow the algo (which honestly there's so much indirection) is if the above is true. Given the rest of the implementation and that the content appears in the slots (I updated the fiddle to add slot eventing to ensure that Safari/FF/Chromium behave the same and they do).

So effectively it comes down to the above definition of the elements, once flattened. Upon my naiive reading of the algo I think Safari does the correct thing here. And then when you consider that there is a test within WPT specifically testing nested slots that technically passes but does not actually pass in Chromium/FF but does in Safari here I think I'm correct that Safari has the correct behavior. I'll file a bug on Chromium.

@gregwhitworth
Copy link

@gregwhitworth gregwhitworth added the standards-gap This represents any work that is currently in the Web Component standard but is not in LWC label Sep 7, 2020
@gregwhitworth
Copy link

This issue was discussed in the CSSWG and the interop difference found here is due to a bug in Safari and in all other areas they are interoperable with other vendors. Since default content can be styled using normal styling it was resolved to clarify the spec using examples (since people on the call that implemented it were confusing what HTML flattening would do to slots) and change the spec to read as the current interop behavior.

Discussion is here: w3c/csswg-drafts#5482

So this issue should be unblocked for support.

@nolanlawson
Copy link
Collaborator

We do not intend to add support for ::slotted to synthetic shadow. This will come with native shadow mode. See: https://rfcs.lwc.dev/rfcs/lwc/0115-mixed-shadow-mode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
standards-gap This represents any work that is currently in the Web Component standard but is not in LWC Synthetic Shadow Synthetic shadow DOM polyfill
Projects
None yet
Development

No branches or pull requests

5 participants