happy_story
happy_story

Reputation: 1155

Why is ::part() not working for slotted Stencil elements?

My HTML:

<my-dropdown label="dropdown" size="m" filter="true">
    <select slot="filter" part="myselect">
      <option>One</option>
      <option>Two</option>
      <option>Three</option>
    </select>
</my-dropdown>

Inside the my-dropdown components, I have a slot:

<slot name="filter" />

The css stylesheet is inside the component, and in it, I have defined:

my-dropdown::part(myselect) { 
..
}

The styles do not apply to the component! Why? Am I not doing it correctly?

Upvotes: 0

Views: 471

Answers (1)

G. Tranter
G. Tranter

Reputation: 17938

Simple answer: Because it's not meant to work on slotted elements.

The CSS parts ::part() pseudo-element selector is used to apply style to elements that are within shadow DOM which use the part attribute.

In your example, you have added the part attribute to the element <select slot="filter" part="myselect"> which is in light DOM not shadow DOM.

Note that slotted elements are not actually moved to the shadow DOM; their position in the DOM is not affected by the slotting mechanism so they exist in regular light DOM like any other element. They are just rendered inside the shadow DOM structure of the parent web component, with both the component's shadow DOM style for that slot (::slotted()) and any regular DOM styling e.g. global stylesheet applied.

In order for the my-dropdown::part(myselect) selector to work, the element that has the part="myselect" attribute would have to be inside the shadow of the my-dropdown component - for example:

@Component({
  tag: 'my-dropdown',
  styleUrl: 'my-dropdown.scss',
  shadow: true,
})
export class MyDropdown {
  render() {
    return (
      <Host>
        <div part="myselect">
          <slot name="filter" />
        </div>
      </Host>
    );
  }
}

Upvotes: 2

Related Questions