Combining the ::slotted and ::part pseudo elements

Viewed 114

I'm trying to use the ::slotted selector in combination with the ::part selector, I want an outer custom element to style a part in an inner custom element, the problem is that I can't get it to work.

So my question is, is my syntax wrong? Is this not possible to do?

Here is a basic example demonstration, I want the parent element to make the button in the child element have a red background

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

customElements.define("parent-element", ParentElement);


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

customElements.define("child-element", ChildElement);
<template id="parent-template">
    <style>
        :host {
            background-color: pink;
            padding: 20px;
        }
        ::slotted(child-element) {
            background-color: blue;
            padding: 10px;
        }
        ::slotted(child-element)::part(button) {
            background-color: red;
        }
    </style>
    <slot></slot>
</template>

<template id="child-template">
    <button part="button">Style me!</button>
</template>

<parent-element>
    <child-element></child-element>
</parent-element>

1 Answers

You could define the style in the parent-element:

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

customElements.define("parent-element", ParentElement);


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

customElements.define("child-element", ChildElement);
<template id="parent-template">
    <style>
        :host {
            background-color: pink;
            padding: 20px;
        }
        ::slotted(child-element) {
            background-color: blue;
            padding: 10px;
        }
    </style>
    <slot></slot>
</template>

<template id="child-template">
    <button part="button">Style me!</button>
</template>

<parent-element>
    <style>
        child-element::part(button) {
            background-color: red;
        }
    </style>
    <child-element></child-element>
</parent-element>

or directly in the child-element:

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

customElements.define("parent-element", ParentElement);


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

customElements.define("child-element", ChildElement);
<template id="parent-template">
    <style>
        :host {
            background-color: pink;
            padding: 20px;
        }
        ::slotted(child-element) {
            background-color: blue;
            padding: 10px;
        }
    </style>
    <slot></slot>
</template>

<template id="child-template">
    <style>
        button {
            background-color: red;
        }
    </style>
    <button part="button">Style me!</button>
</template>

<parent-element>
    <child-element></child-element>
</parent-element>

Related