Slots does not work on a html web component without shadow dom

3.9k Views Asked by At

I have a html web component without shadow dom and I try to add a slot. For some reason it does not work.

I expected it to switch "Foo bar" to "Hello world" but that does not happen.

  1. Does slots only works with shadow dom and a template?
  2. How can I get it to work?

class HelloWorld extends HTMLElement {
  constructor() {
    super();
  }

  connectedCallback() {
    this.innerHTML = `
      <div>
        <slot name="element-name">Foo Bar</slot>
      </div>
    `;
  }
}

customElements.define("hello-world", HelloWorld);
<hello-world>
  <span slot="element-name">Hello World</span>
</hello-world>

1

There are 1 best solutions below

0
On BEST ANSWER

Yes, <slot> only works inside shadowDOM in a native (JSWC) Web Component

or native HTML Element (you can attach shadowDOM to)

Slotted content is reflected lightDOM content

See: ::slotted CSS selector for nested children in shadowDOM slot

A Web Component without shadowDOM only has innerHTML

If you do this.innerHTML= on such a Web Component it replaces the innerHTML, just like on any other HTML tag

with shadowDOM:

<hello-world>
  <b slot="none">Mighty</b>
  <span slot="title">Web Components</span>
  Hello! 
</hello-world>

<script>
customElements.define("hello-world", class extends HTMLElement {
  constructor() {
    super()
      .attachShadow({mode:"open"})
      .innerHTML = `<slot></slot><slot name="title">Foo Bar</slot>`;
    this.onclick = (evt) => this.querySelector('b').slot = "title";
  }
});
</script>