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

问题描述 投票:0回答:3

我在shadowDOM自定义元素模板内应用表格样式,在插槽内,它不接受表格th和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?

javascript css web-component tabular custom-element
3个回答
1
投票

1
投票

您无法从

::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>


0
投票

晚了 3 年,这里有一个替代方案;

my-element[slot=my-slot] tr th { ... }

如果您想将其与自定义元素捆绑在一起,您可以让元素的脚本将该 CSS 注入到父文档中。

© www.soinside.com 2019 - 2024. All rights reserved.