Re: [w3c/webcomponents] Allowing CSS combinators postfixed to the ::slotted() selector (#889)

@castastrophe Thanks for that question! It's not quite what I'm asking about though.

<details>
<summary>
The `::slotted` selector runs within a shadow root context (f.e. in a shadow root `querySelector`, or in a shadow root's `<style>` element), but this is already expected behavior. More details...
</summary>


```js
const root = this.attachShadow(...) // 'this' is a custom element

root.innerHTML = html`
  <style>::slotted(.foo) { ... }</style>
  <slot></slot>
`
```

The `::slotted(.foo)` selector in this example is in fact still be an implementation detail encapsulated inside the (custom element's) shadow root.

The `[slot].foo` selector does a _similar_ thing, but does it from the outside of the custom element (i.e. outside of the shadow root), so it is a tool used on the outside of a custom element's internal shadow tree.

The custom element itself could in fact run this code: `this.querySelector('[slot].foo')`, but the style of the shadow root actually can't contain such a selector as it would not select anything. For example, this won't work the same way:

```
this.attachShadow(...).innerHTML = `
  <style>[slot].foo { ... }</style>
  <slot></slot>
`
```

because it will not select nodes from the light tree that have been "slotted" into the shadow root; instead it will select nodes that are within the shadow root's own DOM that have a `slot=""` attribute.

in other words, calling `this.querySelector('[slot].foo .bar')` on a custom element selects any elements in the light tree with a `slot` attribute _even if they are not actually slotted_.

So inside of a custom element's implementation (in its shadow root), the `::slotted(.foo)` selector is be useful for selecting _actually-slotted_ elements from the light tree, which is something that only the custom element (its shadow root) would care about (otherwise, as @calebdwilliams mentioned, the user would be aware of the shadow root's existence if they could run that selector on the custom element instead of the custom element's (possibly closed) shadow root).

**END DETAILS**

</details>

Anywho, all of the aforementioned is already an existing concept.

The main ask of the OP is to be able to take a selector like `::slotted(.foo)` (which already works, within a shadow root) and to be able to append combinators to it. For example `::slotted(.foo) .bar` or `::slotted(.foo) > .bar`.

As an example, try running the following in your console (tested in Chrome).

What you'll notice is that the square will be colored `deeppink`, but the expected result is for the square to be `cyan`.

The reason is because the `::slotted(.foo)` selector is working fine, but the `::slotted(.foo) .bar` selector doesn't do anything (unlike what we may expect).

```js
class MyEl extends HTMLElement {
 connectedCallback() {
  const root = this.attachShadow({mode: 'open'})
  root.innerHTML = /*html*/ `
   <style>
    :host { display: block; }

    ::slotted(.foo) { /* This works. */
     background: deeppink;
    }

    ::slotted(.foo) .bar { /* This does not work. */
     background: cyan;
    }
   </style>
   <slot></slot>
  `
 }
}

customElements.define('my-el', MyEl)

document.body.insertAdjacentHTML(
 'beforeend',
 /*html*/ `
 <my-el>
  <div class="foo">
   <div>
    <div class="bar"></div>
   </div>
  </div>
 </my-el>

 <style>
  my-el {}
  .foo {
   width: 50px;
   height: 50px;
  }
  .foo div {
   width: 100%;
   height: 100%;
  }
 </style>
`,
)
```

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/889#issuecomment-667636547

Received on Sunday, 2 August 2020 06:48:24 UTC