You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When :has-slotted matches a slot with fallback content, we can conclude that the fallback content is not being displayed.
This is contradicting since a slot's flattened assigned nodes includes its fallback content, meaning the 2nd sentence is not necessarily true since fallback content may be displayed when :has-slotted matches.
The first sentence matches the csswg's resolution here: #6867 (comment).
(FWIW I thought that the relevant resolution was more about nested slots than fallback, FWIW. :has-slotted returning true for fallback feels a bit unfortunate)
@emilio this was pretty prominently discussed in the issue. I don't disagree that the non-functional :has-slotted is pretty limited, but the spec mentions future enhancement via a functional :has-slotted(...) and we also have this issue: #10771.
Generally speaking we want :has-slotted to align to .assignedNodes({flatten:true}). This means the fallback content does make :has-slotted apply. This adheres to the original request in #6867 (comment) because the ask was to determine if the slot has any content (which :empty cannot satisfy because it does not account for slotted content).
Ultimately, I think it comes down to two options:
Option A (including):
:has-slotted would match if an element has any flattened nodes, including fallback content.
:has-slotted:not(:empty) would match on a slot which declared fallback content and was either displaying the fallback content, or non-fallback content.
This is useful for styling a slot based on whether or not it is rendering something.
Option B (excluding):
:has-slotted would match if an element has any flattened nodes, excluding fallback content.
:has-slotted:not(:empty) would match on a slot which declared fallback content but was displaying non-fallback content instead.
This is useful for styling a slot based on whether or not it is rendering non-fallback content.
In both of these cases:
:has-slotted:empty would match if a slot never declared fallback content, but it is being slotted by outside content.
The question then becomes whether or not it is useful to know if the slot is rendering its fallback or not. The original request asked to style a slot has content or not, but did not specify if that content had to be fallback or not. Therefore Option A seems to satisfy that. I haven't seen a compelling usecase for Option B, so we would need evidence of that.
Given we've been unable to decide async, it seems worth taking to the proper agenda.
This stems from the fact that "a non-empty list of flattened slotted nodes" has a precise technical meaning, but "fallback content is not being displayed" does not.
Yes we can't resolve recursive nested content, that's an encapsulation leak (and even if we concede open shadowroots can leak this info, it means we'd have to do weird things like check if the nested slot is in a closed shadowroot). The only reasonable possibility for Option B is that we consider it not:has-slotted if the slot itself is showing fallback, IOW, even if a nested slot is showing fallback, that's still :has-slotted (either way).
On further reflection, the use case noted above wasn't really a good one since ::slotted() does not match fallback content so styling nested fallback content is currently a platform gap, which has been previously mentioned.
Forgive this apparent digression, but I think we need to clarify this potential issue with the spec of ::slotted() since it's relationship to :has-slotted is relevant. I'll file this separately if it needs clarification.
After some discussion with Lit users, @keithamus' Option B makes the most sense but it likely needs new spec text/clarification, especially if the spec for ::slotted() also needs clarification.
Here's the reasoning:
Previously it's been mentioned that :has-slotted should align with assignedNodes({flatten: true}). This is true excluding the 3rd point here: this function gives: (1) the flattened true, (2) includes text nodes, (3) includes fallback content.
With point 3 excluded, :has-slotted is mostly aligned with ::slotted which is desirable. However, it would change the 2nd point here: :slotted() matches (1) the flattened tree, (2) elements, (3) and does not consider fallback.
The non-functional :has-slotted instead should resolve against nodes and not elements. This will align ::slotted() with the future functional :has-slotted() that should also only consider elements.
For fallback content not matching:
In scope fallback content can be directly targeted so it does not need a special selector to reach.
Fallback content itself, including distributed flattened fallback content, cannot be targeted with ::slotted, so it should also not be relevant for :has-slotted. The ability to target fallback content specifically should be addressed in the future with a complimentary feature.
Activity
sorvell commentedon Aug 11, 2026
Example test
Currently:
emilio commentedon Aug 11, 2026
cc @keithamus
(FWIW I thought that the relevant resolution was more about nested slots than fallback, FWIW.
:has-slottedreturning true for fallback feels a bit unfortunate)sorvell commentedon Aug 11, 2026
@emilio this was pretty prominently discussed in the issue. I don't disagree that the non-functional
:has-slottedis pretty limited, but the spec mentions future enhancement via a functional:has-slotted(...)and we also have this issue: #10771.keithamus commentedon Aug 12, 2026
Seems like we can async resolve on this? /cc @astearns
Proposed Resolution: Edit the text to say
woody-li commentedon Aug 17, 2026
Why not using:
It's unambiguous.
:has-slottedonly to match an element which has any flatten assigned nodes (excludes the fallback content).:not(:has-slotted, :empty)to match which the fallback content is displayed.:empty:not(:has-slotted)to match the real empty slot.astearns commentedon Aug 17, 2026
Am I reading correctly that so far there are two opinions for matching with fallback content and two opinions for not matching with fallback content?
keithamus commentedon Aug 18, 2026
Generally speaking we want
:has-slottedto align to.assignedNodes({flatten:true}). This means the fallback content does make:has-slottedapply. This adheres to the original request in #6867 (comment) because the ask was to determine if the slot has any content (which:emptycannot satisfy because it does not account for slotted content).Ultimately, I think it comes down to two options:
Option A (including):
:has-slottedwould match if an element has any flattened nodes, including fallback content.:has-slotted:not(:empty)would match on a slot which declared fallback content and was either displaying the fallback content, or non-fallback content.Option B (excluding):
:has-slottedwould match if an element has any flattened nodes, excluding fallback content.:has-slotted:not(:empty)would match on a slot which declared fallback content but was displaying non-fallback content instead.In both of these cases:
:has-slotted:emptywould match if a slot never declared fallback content, but it is being slotted by outside content.The question then becomes whether or not it is useful to know if the slot is rendering its fallback or not. The original request asked to style a slot has content or not, but did not specify if that content had to be fallback or not. Therefore Option A seems to satisfy that. I haven't seen a compelling usecase for Option B, so we would need evidence of that.
Given we've been unable to decide async, it seems worth taking to the proper agenda.
woody-li commentedon Aug 19, 2026
The option B (excluding) will bring more more possibilities.
And also can resolve #10771
sorvell commentedon Aug 21, 2026
I think this is more complex than it seems. Let's say the author of
x-awants anything a user places in theslotto be "green."TLDR: they can't distinguish whether what is placed there is itself a slot with fallback content or something else.
It may seem straightforward not to match
:has-slottedhere and not make the fallback "green":But consider this case. Presumably the author of
x-awants this to be green, but they can't know if thex-bcontent is fallback or not.This stems from the fact that "a non-empty list of flattened slotted nodes" has a precise technical meaning, but "fallback content is not being displayed" does not.
keithamus commentedon Aug 21, 2026
Yes we can't resolve recursive nested content, that's an encapsulation leak (and even if we concede open shadowroots can leak this info, it means we'd have to do weird things like check if the nested slot is in a closed shadowroot). The only reasonable possibility for Option B is that we consider it not
:has-slottedif the slot itself is showing fallback, IOW, even if a nested slot is showing fallback, that's still:has-slotted(either way).sorvell commentedon Aug 22, 2026
On further reflection, the use case noted above wasn't really a good one since
::slotted()does not match fallback content so styling nested fallback content is currently a platform gap, which has been previously mentioned.sorvell commentedon Aug 22, 2026
Forgive this apparent digression, but I think we need to clarify this potential issue with the spec of
::slotted()since it's relationship to:has-slottedis relevant. I'll file this separately if it needs clarification.@keithamus
Please check me on this: I'd also like to point out that there may be an inconsistency in the spec with respect to
::slotted. Specifically:Step 4 of "assigned, after flattening" says:
Since "Element and Text nodes, are slottables," I'm not sure why that wouldn't include fallback content.
But...
::slotted(*)does not match fallback content.sorvell commentedon Aug 27, 2026
After some discussion with Lit users, @keithamus' Option B makes the most sense but it likely needs new spec text/clarification, especially if the spec for
::slotted()also needs clarification.Here's the reasoning:
:has-slottedshould align withassignedNodes({flatten: true}). This is true excluding the 3rd point here: this function gives: (1) the flattened true, (2) includes text nodes, (3) includes fallback content.:has-slottedis mostly aligned with::slottedwhich is desirable. However, it would change the 2nd point here::slotted()matches (1) the flattened tree, (2) elements, (3) and does not consider fallback.:has-slottedinstead should resolve against nodes and not elements. This will align::slotted()with the future functional:has-slotted()that should also only consider elements.::slotted, so it should also not be relevant for:has-slotted. The ability to target fallback content specifically should be addressed in the future with a complimentary feature.