私は、Polymer などのサードパーティ ライブラリを使用せずに、 Web コンポーネントに最初の一歩を踏み出しています。主なセールス ポイントの 1 つは、Web コンポーネントのスタイルが他の場所で定義されたスタイルから分離されているため、コンポーネントのシャドウ DOM をサンドボックスのような環境でスタイル設定できることです。
私が直面している問題は、スタイルがスロット要素をどのようにカスケードするかです。スロット要素はシャドウ DOM の一部ではないため::slotted()
、コンポーネント テンプレート内のセレクターでのみターゲットにすることができます。これは素晴らしいことですが、外部で定義されたスタイルもスロット要素に無敵の特異性*で適用されるため、Web コンポーネントがすべてのコンテキストで正しく表示されることを保証することはほとんど不可能です。
*他にも!important
。
この問題は、次のように要約できます。
customElements.define("my-nav",
class extends HTMLElement {
constructor() {
super();
const template = document.querySelector("template#my-nav").content;
this.attachShadow({ mode: "open" })
.appendChild(template.cloneNode(true));
}
}
);
a {
color: red; /* >:( */
}
<template id="my-nav">
<style>
.links-container ::slotted(a) {
color: lime;
font-weight: bold;
margin-right: 20px;
}
</style>
<div class="links-container">
<slot name="links"></slot>
</div>
</template>
<p>I want these links to be green:</p>
<my-nav>
<a href="#" slot="links">Link 1</a>
<a href="#" slot="links">Link 2</a>
<a href="#" slot="links">Link 3</a>
</my-nav>
この「機能」の価値を理解するのに苦労しています。リンクを他の形式で指定して JS でノードを作成するか!important
、color プロパティに追加する必要があります。これは、文字通り、定義していない他のプロパティに関しては一貫性を保証しません。
この問題はどこかで対処されていますか、それともライト DOM 構造を変更することで簡単に解決できますか? リンクのリストをスロットに取得する方法が他にわかりません。