Fallback content on an "unnamed" slot is never displayed

838 views Asked by At

I'm trying to figure out how web components are working and can't fully understand rules around fallback content in slots:

I have a web-component like:

const template = document.createElement('template');
template.innerHTML = `
  <slot name="content">
    <span>fallback</span>
  </slot>
  <slot>
    <span>fallback on an anonymus slot</span>
  </slot>
  <section>...and more content form shadow DOM</section>
`;

class SomeComponent extends HTMLElement{
  constructor() {
    super();

    const shadowRoot = this.attachShadow({mode: 'open'});
    shadowRoot.appendChild(template.content.cloneNode(true));
  }
}

window.customElements.define('some-component', SomeComponent);

and if I put this component on a page like

<some-component>
  <span slot="content">named slot content</span>
</some-component>

I never see a "fallback" content for unnamed slot:

enter image description here

but it does present in the shadow DOM:

enter image description here

I don't use any pollyfills and rely on current Chrome web-components support

1

There are 1 answers

0
Supersharp On BEST ANSWER

It's the expected behavior. Actually the fallback sould not be display because some elements are caught and revealed by the unnamed <slot> element: the (invisible space and CRLF) text elements before the <span> and after the </span> tags.

If you remove them:

<some-component><span slot="content">named slot content</span></some-component>

...then you will see the fallback text!

const template = document.createElement('template');
template.innerHTML = `
  <slot name="content">
    <span>fallback</span>
  </slot>
  <slot>
    <span>fallback on an anonymus slot</span>
  </slot>
  <section>...and more content form shadow DOM</section>
`;

class SomeComponent extends HTMLElement{
  constructor() {
    super();

    const shadowRoot = this.attachShadow({mode: 'open'});
    shadowRoot.appendChild(template.content.cloneNode(true));
  }
}

window.customElements.define('some-component', SomeComponent);
<some-component><span slot="content">named slot content</span></some-component>