如何在自定义元素中的插槽内进行CSS样式设置?

问题描述

我正在将表格样式应用于shadowDOM自定义元素模板中的插槽中,它不接受表格和td CSS。

class Table extends HTMLElement {

  constructor() {
    super();
    // console.log("this accordion -> ",this)
    setTimeout(() => {

      const template = document.createElement('template');
      template.innerHTML = `
        <style>
          ::slotted(table) {
              color: red;
              width: 100%;
          }

          ::slotted(table tr th),::slotted(table tr td) {
              text-align: left;
              padding: 10px 0;
          }

        </style>
        <slot></slot>
      `;
      const shadowDOM = this.attachShadow({
        mode: 'open'
      });
      shadowDOM.appendChild(template.content.cloneNode(true));

    },0);

  }
  
}

customElements.define('t-table',Table);
<t-table>
  <table>
    <tr>
      <th>Sl No.</th>
      <th>Name</th>
    </tr>
    <tr>
      <td>1</td>
      <td>Name</td>
    </tr>
  </table>
</t-table>

如何在上述情况下应用CSS?

解决方法

您无法从::slotted伪元素选择器中选择子级。
这是设计使然;组件不应该关心开槽元素的样式。例外是正在插入的元素,但不是其后代。

以老式的方式从Light DOM中设置元素的样式。

class Table extends HTMLElement {

  constructor() {
    super();

    const template = document.createElement('template');
    template.innerHTML = `
      <style>
        ::slotted(table) {
            color: red;
            width: 100%;
        }
      </style>
      <slot></slot>
    `;
    const shadowDOM = this.attachShadow({
      mode: 'open'
    });
    shadowDOM.appendChild(template.content.cloneNode(true));

  }
  
}

customElements.define('t-table',Table);
.my-table tr th,.my-table tr td {
    text-align: left;
    padding: 10px 0;
}
<t-table>
  <table class="my-table">
    <tr>
      <th>Sl No.</th>
      <th>Name</th>
    </tr>
    <tr>
      <td>1</td>
      <td>Name</td>
    </tr>
  </table>
</t-table>

但是您的影子模板除了将样式应用于插槽元素之外,并没有创建其他布局或其他任何东西,实际上并没有做任何其他事情,那么为什么还要使用Shadow DOM?只需在Light DOM的t-table元素上应用样式,您将获得相同的效果。

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

customElements.define('t-table',Table);
t-table table {
    color: red;
    width: 100%;
}

t-table tr th,t-table tr td {
    text-align: left;
    padding: 10px 0;
}
<t-table>
  <table>
    <tr>
      <th>Sl No.</th>
      <th>Name</th>
    </tr>
    <tr>
      <td>1</td>
      <td>Name</td>
    </tr>
  </table>
</t-table>

,

请参阅StackOverflow答案:::slotted CSS selector for nested children in shadowDOM slot