【问题标题】:Interaction between CSS grid and mixed shadowDOM/lightDOMCSS 网格和混合 shadowDOM/lightDOM 之间的交互
【发布时间】:2021-03-05 23:37:59
【问题描述】:

我目前正在尝试自定义元素中的插槽。

看这个简单的例子:

customElements.define('x-y', class extends HTMLElement {
  constructor() {
    super();
    let template = document.createElement('template');
    template.innerHTML = `<style>
    :host { display: block; align-self: normal; }
    div {
      background-color: #666;
      color: white;
      padding: 5px;
    }
  </style>
  <div>affected by styles from ShadowDOM</div>
  <slot name="content"></slot>`;

    const shadowRoot = this.attachShadow({
      mode: 'open'
    }).appendChild(template.content.cloneNode(true));
  }
})
body {
  border: 2px dashed magenta;
  display: grid;
  height: 100vh;
  grid-template-rows: minmax(0, 1fr);
  margin: 0;
}

* {
  box-sizing: border-box;
}

x-y>div {
  background-color: #f0f0f0;
  padding: 5px;
}

.inner-grid {
  display: grid;
  grid-template-rows: 1fr 2fr;
  height: 100%;
  overflow: auto;
}
<x-y class="inner-grid">
  <div slot="content">not affected by styles from ShadowDOM</div>
</x-y>

正如我们所见,.inner-grid 的网格定义虽然在页面的 CSS 中定义,但确实会影响 shadowDOM 内容的显示。

这虽然很方便,但有点出乎意料,因为外部 CSS 不应该影响 Web 组件的内部(例外是继承属性和自定义属性)。

我的第二个期望——也被违反了——是一个网格容器使它的直接子代成为网格单元格,如果有的话,网格模板定义适用于这些单元格。 shadowDOM 中的元素怎么会是这样的直接子元素?

这是 Chrome 元素检查器中的结构:

问:谁能解释一下具体是如何工作的? CSS 网格如何与 shadow DOM / light DOM 混合内容交互?请添加参考,如果有的话。

【问题讨论】:

    标签: javascript html css-grid shadow-dom custom-element


    【解决方案1】:

    我尝试使用我自己的代码来理解您的问题。

    所以我把你的 .inner-grid 放在 3 列网格 &lt;game-board&gt; 元素上

    你的问题 #1

    我们可以看到,.inner-grid 的网格定义,虽然定义了 在页面的 CSS 中,确实会影响页面内容的显示 shadowDOM。

    您在哪里看到这会影响 shadowDOM 的内容”

    红色背景是什么意思?

    shadowRoot 被认为是一个元素,占用空间,因此是 1fr

    然后display:grid; grid-template-rows:repeat( 3 , 1fr ); 在容器上会将容器延伸到 3 倍(因此间接其 shadowRoot)高度。

    你的问题 #2

    我的第二个期望——也被违反了——是一个网格 容器使它的直接子节点成为网格单元格, 网格模板定义适用(如果有)。里面的元素是怎样的 shadowDOM 这么直接的孩子?

    SLOT(或者实际上是开槽的内容/“分布式节点”)是网格中的直接子节点

        <slot name="A1"></slot>  <slot name="A2"></slot>            <slot></slot>
        <slot name="B1"></slot>  <span>gridded in shadowDOM</span>  <slot name="B2"></slot>
    

    作为 3x2 网格工作

    注意:

    • SLOTA2 中什么都没有,它没有填满网格区域
    • 来自 lightDOM 的 2 个元素进入默认插槽 &lt;slot&gt;&lt;/slot&gt; 并填充 2 个网格区域。

    <template id=GAME-BOARD>
      <style description="style shadowDOM">
        div {
          background: lightgreen;
          display: grid; grid-template-columns: repeat(3, 1fr)  }
        ::slotted(*) { border: 3px dashed green }
      </style>
      <div>
        <slot name="A1"></slot> <slot name="A2"></slot>           <slot></slot>
        <slot name="B1"></slot> <span>gridded in shadowDOM</span> <slot name="B2"></slot>
      </div>
    </template>
    <style description="lightDOM game-pieces">
     game-board{ background:red; display:grid; grid-template-rows:repeat(3,1fr)}
     game-piece{ background:lightblue }
    </style>
    <game-board>
      <game-piece>to default slot!</game-piece>
      <game-piece slot="A1"></game-piece>
      <game-piece slot="B2"></game-piece>
      <div>GRIDDED from ligthDOM to default slot</div>
    </game-board>
    <script>
      customElements.define('game-board', class extends HTMLElement {
        constructor() {
          super().attachShadow({mode: 'open'})
                 .append(document.getElementById(this.nodeName).content.cloneNode(true));
        }})
      customElements.define('game-piece', class extends HTMLElement {
        connectedCallback() {
          this.innerHTML = this.getAttribute("slot") || "NO SLOT";
        }})
    </script>

    如果你想创建一个棋盘,你需要在 64 个 SLOT 的每个中默认放置一个元素。这些也是捕捉拖动/触摸动作所必需的。

    那么使用命名为 grid-template-areas(在 shadowDOM 中)会更容易。

    并使用 (64) 个 CSS 选择器定位:

     ::slotted([slot="A5"]){ grid-area:A5 }
    

    并使用默认的&lt;slot&gt;&lt;/slot&gt; 来捕获未定位在棋盘上的棋子。

    2 年前,我用组件做了一个Chessboardhttps://chessmeister.github.io(没有使用我现在知道的所有东西)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      • 2012-09-06
      相关资源
      最近更新 更多