Pewarta Proxy

📋 Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

⚙️ Pengaturan Proxy Target

Skip to content

[css-shadow] :has-slotted spec contradicts itself #14307

Open

Description

@sorvell

The spec says:

The :has-slotted pseudo-class matches slot elements which have a non-empty list of flattened slotted nodes.

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).

The 2nd sentence should likely just be removed.

Activity

  1. sorvell commented on Aug 11, 2026

    @sorvell
    Author

    Example test

    Currently:

    • Chrome Canary 153.0.8002.0: agrees with the first sentence.
    • Firefox 153.0.4: agrees with the second sentence.
  2. emilio commented on Aug 11, 2026

    @emilio
    Collaborator

    cc @keithamus

    (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)

  3. sorvell commented on Aug 11, 2026

    @sorvell
    Author

    @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.

  4. keithamus commented on Aug 12, 2026

    @keithamus
    Member

    Seems like we can async resolve on this? /cc @astearns

    Proposed Resolution: Edit the text to say

    '':has-slotted'' matches when the fallback content is being displayed..

  5. woody-li commented on Aug 17, 2026

    @woody-li

    Why not using:

    `:has-slotted` should match when the fallback content is not being displayed
    

    It's unambiguous.

    • Using :has-slotted only to match an element which has any flatten assigned nodes (excludes the fallback content).
    • Using :not(:has-slotted, :empty) to match which the fallback content is displayed.
    • Using :empty:not(:has-slotted) to match the real empty slot.
  6. astearns commented on Aug 17, 2026

    @astearns
    Member

    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?

  7. keithamus commented on Aug 18, 2026

    @keithamus
    Member

    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.

  8. woody-li commented on Aug 19, 2026

    @woody-li

    The option B (excluding) will bring more more possibilities.
    And also can resolve #10771

  9. sorvell commented on Aug 21, 2026

    @sorvell
    Author

    I think this is more complex than it seems. Let's say the author of x-a wants anything a user places in the slot to 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-slotted here and not make the fallback "green":

    <x-a><template shadowrootmode="open">
      <style>:has-slotted { color: green; }</style>
      <slot>fallback</slot>
    </template></x-a>

    But consider this case. Presumably the author of x-awants this to be green, but they can't know if the x-b content is fallback or not.

    <x-b><template shadowrootmode="open">
      <x-a><template shadowrootmode="open">
        <style>:has-slotted { color: green; }</style>
        <slot>fallback</slot>
      </template><slot>nested fallback</slot></x-a>
    </template></x-b>

    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.

  10. keithamus commented on Aug 21, 2026

    @keithamus
    Member

    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).

  11. sorvell commented on Aug 22, 2026

    @sorvell
    Author

    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.

  12. sorvell commented on Aug 22, 2026

    @sorvell
    Author

    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.

    @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:

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

    Step 4 of "assigned, after flattening" says:

    If slottables is the empty list, then append each slottable child of slot, in tree order, to slottables.

    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.

  13. sorvell commented on Aug 27, 2026

    @sorvell
    Author

    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:

    1. 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.
    2. 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.
    3. 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.
    4. For fallback content not matching:
      1. In scope fallback content can be directly targeted so it does not need a special selector to reach.
      2. 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions