HTMLWebコンポーネントはShadowDOMスタイルを使用しません
バニラWebコンポーネントまたはHTML要素を作成しました。2つのリンクが表示されるだけです。
物事をカプセル化するために、私はシャドウDOMを使用します。ただし、カプセル化されていないようです。DOMツリーでは、これは#shadow-root内にあります。
Webコンポーネントが、Webコンポーネントのテンプレートで提供したスタイルではなく、グローバルスタイルを使用するのはなぜですか?
テキストは赤で、緑になると思っていました。
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>
回答
この質問にはすでに受け入れられている答えがありますが、スロットの子をshadowRootに移動することは、ほとんどのユースケースでは望ましくありません。
おそらくやりたいことは、::slotted()
セレクターを使用することです。
::slotted()
セレクターを介してスロットの子に適用されたスタイルは「デフォルト」スタイルとしてのみ機能し、ライトDOMでスタイルを使用することでオーバーライドできることに注意してください。
たとえば、スニペットの次の編集済みバージョンを確認してください。
ご覧のとおり、今回my-el
は色とテキスト装飾スタイルの両方を適用して、(<a>
)子をそのスロットのいずれかに固定しようとします。
ただし、ライトドムでは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>
完全で詳細な説明は次のとおりです。:: shadowDOMスロットにネストされた子用のスロット付きCSSセレクター
TL; DR
リンクはlightDOMにあるため、そのDOM(コードではドキュメントDOM)によってスタイルが設定されます。
ノードをlightDOMからshadowDOMに移動することは1つの「解決策」です。しかし、あなたはその時スロットを使用していません。
参考までに、コードは次のように圧縮できます。
class MyEl extends HTMLElement {
constructor() {
super().attachShadow({ mode: "open" })
.innerHTML = `<style>a{color:green}</style><slot></slot>`;
}
}
window.customElements.define("my-el", MyEl);
StackOverflow Search:Custom Elements SLOTsで、 SLOT関連のその他の回答を見つけることができます。
この行を観察してください。たとえば、次のように要素をシャドウに移動/コピーする必要があります。
this.shadow.innerHTML = this.innerHTML + template;
インラインスタイルのみがshadowdom要素に適用されることを示すためにこれを追加しました..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>