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-scoping-1] add :has-slotted() pseudo class #10586

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

keithamus
Copy link
Member

Based on the discussion in #6867, and the conclusions within, I thought I'd have a go at specifying a :has-slotted( <<compound-selector>> ) pseudo class.

I put this in css-scoping-1; the resolution was to add it in css-selectors-5 but I thought it might be useful living next to :host, :host(), :host-context() and ::slotted(). I am of course happy to move it if folks disagree with this choice.

My intent for this PR is largely to present something worthy of discussion. I hope I've achieved that, apologies if this PR amounts to just noise.

@nt1m nt1m changed the title [css-scoping-1] add :has-slotted() psuedo class [css-scoping-1] add :has-slotted() pseudo class Jul 17, 2024
The <dfn selector>:has-slotted()</dfn> pseudo-class, when evaluated
<a>in the context of a shadow tree</a>,
matches the <a>slot</a>, if one of its
<a lt="find flattened slottables">assigned, after flattening,</a> matches the provided <<compound-selector>>.
Copy link

@justinfagnani justinfagnani Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"if one of its assigned, after flattening, matches "

Is there a missing word there? "child elements"?

<pre>
&lt;x-foo>
&lt;div id="one" slot="foo" class="foo">...&lt;/div>
&lt;"shadow tree">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to use the <::shadow> markup here?

@Westbrook
Copy link

Exciting start! Points to the need for :host:has(...) support so that we aren't required to ship arbitrary wrapping elements, but that's a argument for another day.

If you haven't already, I think I might take a pass some tentative WPTs based on this outline during the week of the 12th.

The <dfn selector>:has-slotted()</dfn> pseudo-class, when evaluated
<a>in the context of a shadow tree</a>,
matches the <a>slot</a>, if one of its
<a lt="find flattened slottables">assigned elements, after flattening,</a> matches the provided <<compound-selector>>.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"after flattening" is interesting here because it give "non-slotted" content while being required to gather all slotted content. E.G.:

<div>
  <template shadowrootmode="open">
    <style>
      div {
        color: green;
      }
      :has-slotted(div) {
        color: red;
      }
    </style>
    <slot><div>Test</div></slot>
  </template>
</div>

In the example above "Test" will display red in the case that flattened elements are leveraged.

However, if you don't use flattened elements:

<div>
  <template shadowrootmode="open">
    <div>
      <template shadowrootmode="open">
        <style>
          div {
            color: green;
          }
          :has-slotted(div) {
            color: red;
          }
        </style>
        <slot></slot>
      </template>
      <slot><div>Test</div></slot>
    </div>
  </template>
</div>

This "Test" will also be red. And, without flattened elements,

<div>
  <template shadowrootmode="open">
    <div>
      <template shadowrootmode="open">
        <style>
          div {
            color: green;
          }
          :has-slotted(div) {
            color: red;
          }
        </style>
        <slot></slot>
      </template>
      <div>Test</div>
    </div>
  </template>
</div>

This "Test" will also be red.

I'm not sure it's a real thing, but is there a place between ::slotted(*) and .assignedElements({flatten: true}) that would resolve the external assigned to a slot and not the default ones internal to the shadow host?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency, I think it's important that :has-slotted matches using the same rules for matchable elements as ::slotted.

Concretely, since ::slotted() never matches either <slot> or fallback content, :has-slotted also should not match when it would by selecting either <slot> or fallback content.

See #5482. IMO, the spec is still very confusing and possibly indicates that this should match, but the CSS working group resolved that the current behavior is intended in #5482.

I think matching against fallback content both for ::slotted and :has-slotted is valuable, but I suggest it should be tackled as a follow-on to this feature.

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

Successfully merging this pull request may close these issues.

4 participants