HTML 웹 구성 요소는 Shadow DOM 스타일을 사용하지 않습니다.

Aug 15 2020

바닐라 웹 구성 요소 또는 HTML 요소를 만들었습니다. 두 개의 링크 만 표시됩니다.

이를 캡슐화하기 위해 Shadow DOM을 사용합니다. 그러나 캡슐화되지 않은 것 같습니다. DOM 트리에서 그것은 좋은 # shadow-root 안에 있습니다.

웹 구성 요소가 내 웹 구성 요소의 템플릿에서 제공 한 스타일 대신 전역 스타일을 사용하는 이유는 무엇입니까?

텍스트는 빨간색이고 초록색 일 것으로 예상했습니다.

class MyEl extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({ mode: "open" });
  }

  connectedCallback() {
    const template = `
      <style>
        a {
          color: green;
        }
      </style>
      <slot></slot>`;
    this.shadow.innerHTML = template;
  }
}

window.customElements.define("my-el", MyEl);
a {
  color: red
}
  <my-el>
    <a href="example.com">Item1</a>
    <a href="example.com">Item2</a>
  </my-el>

답변

1 AlanDávalos Aug 17 2020 at 15:12

이 질문에는 이미 허용 된 답변이 있지만 슬롯의 자식을 shadowRoot로 이동하는 것은 대부분의 사용 사례에서 바람직하지 않습니다.

아마도 당신이 원하는 것은 ::slotted()선택기 를 사용하는 것 입니다.

::slotted()선택기를 통해 슬롯의 자식에 적용된 스타일 은 "기본"스타일로만 작동하며 여전히 light DOM에서 스타일을 사용하여 재정의 할 수 있습니다.

예를 들어,이 편집 된 버전의 스 니펫을 확인하십시오.

보시다시피 이번에 my-el는 색상과 텍스트 장식 스타일을 모두 <a>슬롯에있는 앵커 ( ) 자식에 적용하려고 합니다.

그러나 light dom a.special에는 색상을 재정의 하는 선택기가 있으므로 <a class="special">녹색이 아닌 빨간색 이 됩니다.

class MyEl extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({ mode: "open" });
  }

  connectedCallback() {
    const template = `
      <style>
        ::slotted(a) {
          color: green;
          text-decoration: none;
        }
      </style>
      <slot></slot>`;
    this.shadow.innerHTML = template;
  }
}

window.customElements.define("my-el", MyEl);
a.special {
  color: red
}
  <my-el>
    <a href="example.com">Item1</a>
    <a class="special" href="example.com">Item2</a>
  </my-el>

1 Danny'365CSI'Engelman Aug 15 2020 at 23:44

전체, 자세한 설명은 다음과 같습니다. :: shadowDOM 슬롯에 중첩 된 자식을위한 슬롯 CSS 선택기

TL; DR

링크는 lightDOM에 있으므로 DOM에 의해 스타일이 지정됩니다 (코드에서 DOM 문서).
lightDOM에서 shadowDOM으로 노드를 이동하는 것은 하나의 "솔루션"입니다. 그러나 당신은 슬롯을 사용하지 않습니다.

참고로 코드를 다음과 같이 압축 할 수 있습니다.

class MyEl extends HTMLElement {
  constructor() {
    super().attachShadow({ mode: "open" })
           .innerHTML = `<style>a{color:green}</style><slot></slot>`;

  }
}

window.customElements.define("my-el", MyEl);

더 많은 SLOT 관련 답변은 StackOverflow Search : Custom Elements SLOTs 에서 찾을 수 있습니다.

KresimirPendic Aug 15 2020 at 19:57

이 선을 관찰하면 다음과 같이 요소를 그림자로 이동 / 복사해야합니다.

this.shadow.innerHTML = this.innerHTML + template;

인라인 스타일 만 shadow dom 요소에 적용된다는 것을 보여주기 위해 이것을 추가했습니다. .. SD에 복사 된 링크가 스타일을 사용하고 있습니다. :)

그래서 빨간색 이 될 것입니다 GLOBAL, 녹색 됩니다 SHADOW요소

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

  connectedCallback() {
    this.shadow = this.attachShadow({ mode: "open" });
    const template = `
      <style>
        a {
          color: green;
        }
      </style>
      <slot></slot>`;
    this.shadow.innerHTML = this.innerHTML + template;
  }
}

window.customElements.define("my-el", MyEl);
a {
  color: red
}
<my-el>
    <a href="example.com">Item1</a>
    <a href="example.com">Item2</a>
  </my-el>