Combining ::slotted with pseudo-elements

Viewed 329

I'm trying to figure out what's the deal with combining pseudo-elements with the ::slotted selector, looks like it works with some but not with others and I can't find any documentation listing the selectors it works with

Here is a demonstration of the problem, notice how some pseudo-selectors take effect while others don't

class TestElement extends HTMLElement {
    constructor() {
        super();
        this.attachShadow({mode: 'open'});
        let template = document.querySelector("template");
        this.shadowRoot.append(template.content.cloneNode(true));
    }
}

customElements.define("test-element", TestElement);
<template>
    <style>
        
        ::slotted(*)::first-line { /* doesn't works */
            color: red;
        }
        ::slotted(*):first-letter { /* doesn't works */
            color: red;
        }
        ::slotted(*) {
            max-height: 3em;
            overflow: auto;
        }
        ::slotted(*)::-webkit-scrollbar { /* doesn't works */
            width: 3px;
        }
        ::slotted(*)::-webkit-scrollbar-track { /* doesn't works */
            background-color: red;
        }
        ::slotted(*)::selection { /* doesn't works */
            color: red;
        }
        ::slotted(*)::placeholder { /* works */
            color: red;
        }
        ::slotted(*)::marker { /* works */
            color: red;
        }
    </style>
    <slot></slot>
</template>

<test-element>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente
    doloribus ullam fugit ipsum laborum velit architecto, provident dolore
    at, aperiam quaerat officiis aliquid magni sed expedita totam dolor
    doloremque odit.
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente
    doloribus ullam fugit ipsum laborum velit architecto, provident dolore
    at, aperiam quaerat officiis aliquid magni sed expedita totam dolor
    doloremque odit.
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente
    doloribus ullam fugit ipsum laborum velit architecto, provident dolore
    at, aperiam quaerat officiis aliquid magni sed expedita totam dolor
    doloremque odit.</p>
</test-element>

<test-element>
    <input placeholder="Placeholder">
</test-element>

<test-element>
    <li>Li</li>
</test-element>

1 Answers

Good find on ::placeholder and ::marker

But ::marker does not work in Mozilla's browser (haven't tested safari)

In general ::slotted() only takes a simple selector;
see: ::slotted CSS selector for nested children in shadowDOM slot

Side note: your constructor can be written as:

constructor() {
  let template = document.querySelector("template"); // valid code *before* super()
  super() // sets and returns this scope
    .attachShadow({mode: 'open'}) // sets and returns this.shadowRoot
    .append(template.content.cloneNode(true));
}
Related