シャドウ要素で見つかったスタイルを変更する方法はありますか?具体的には、cssclassにあるいくつかのプロパティを拡張/上書きしますか?私は Beanote というchrome-extensionを使用していますが、これは4月(2017)から更新されておらず、修正したい厄介なバグがあります。 1行のcssでパッチが十分に当てはまることがわかりましたが、シャドウ要素自体の内部に入り、開発ツールでこれらのスタイルを直接編集せずに適用することに途方に暮れています。
私はこの方法を探しています:
/*global css rule*/
.the-class-name { property-name: my-value; }
これを上書きするには:
/* style tag inside the shadow-root */
.the-class-name { property-name: bad-value; }
オンラインで見つけたほとんどのリソースで、shadow-root override style
またはedit shadow-root styling
に関係がありました:Host
これは、これが意図されている場合、私のニーズや::shadow
。
Shadow DOMの機能であるスタイルの分離のため、Shadow DOMスコープで適用されるグローバルCSSルールを定義することはできません。
CSS変数を使用することも可能ですが、シャドウコンポーネントに明示的に実装する必要があります(このサードパーティライブラリの場合はそうではありません)。
回避策は、スタイルのラインをシャドウDOMに直接注入することです。
//Host is the element that holds the shadow root:
var style = document.createElement( 'style' )
style.innerHTML = '.the-class-name { property-name: my-value; }'
Host.shadowRoot.appendChild( style )
注意:Shadow DOM mode
が'open'
に設定されている場合にのみ機能します。
2019年のChrome 73+およびOpera 60 +の更新
CSSStyleSheetオブジェクトを直接インスタンス化し、シャドウDOMまたはドキュメントに影響を与えることができるようになりました。
var sheet = new CSSStyleSheet
sheet.replaceSync( `.color { color: pink }`)
Host.shadowRoot.adoptedStyleSheets = [ sheet ]
Ionic V4の選択アイコンの色変更の例
document.querySelector('#my-select').shadowRoot.querySelector('.select-icon-inner').setAttribute('style', 'opacity:1');
ionViewDidEnter() {
document.querySelector('#my-select').shadowRoot.querySelector('.select-icon-inner').setAttribute('style', 'opacity:1');
}
デフォルトで生成されたshadowRootスタイルを上書きする場合は、ページが完全にロードされた後にjs関数を呼び出す必要があります。
以前の回答を拡張します。
外側のスタイルは、Shadow DOMで定義されたスタイルよりも常に優先されます。つまり、スタイリングしているコンポーネントを参照するグローバルスタイルルールを追加した場合です。参照: https://developers.google.com/web/fundamentals/web-components/shadowdom#stylefromoutside
それ以外の場合、これは要素のシャドウDOMがstyleSheet
で埋め込まれているか、またはadoptedStyleSheets
を使用してスタイルシートを採用しているかに依存します。
要素が要素に埋め込まれている場合、addRule
またはinsertRule
を使用して、既存のスタイルシートにルールを追加または挿入できます。これは、adopedStyleSheets
で追加されたスタイルシートでも機能します。
前の回答で述べたように、代わりに採用されたスタイルシートのリストに新しいスタイルシートを追加できます。これは、styleSheet
が優先され、adoptedStyleSheets
は読み取り専用プロパティであるため、shadowRootにstyleSheetList
が埋め込まれている場合にも機能します。
assert(myElement.shadowRoot.styleSheets.length != 0);
myElement.shadowRoot.styleSheets[0].addRule(':Host', 'display: none;');
assert(myElement.shadowRoot.adoptedStyleSheets.length != 0);
`myElement.shadowRoot.adoptedStyleSheets[0].addRule(':Host', 'display: none;');`
const sheet = new CSSStyleSheet();
sheet.replaceSync(`:Host { display: none; }`);
const elemStyleSheets = myElement.shadowRoot.adoptedStyleSheets;
// Append your style to the existing style sheet.
myElement.shadowRoot.adoptedStyleSheets = [...elemStyleSheets, sheet];
// Or if just overwriting a style set in the embedded `styleSheet`
myElement.shadowRoot.adoptedStyleSheets = [sheet];
ホスティングアプリケーションからWebComponentをカスタマイズする問題を解決する良い、私見の方法を指摘しているので、コメントの1つで@Renatoによって与えられた答えを2番目にしたいと思います。
@Supersharpは、外部CSSルールがnotであるという事実に正しく、シャドウルートに伝播します。これは仕様によるものです。
CSS変数は良い方向ですが、私の個人的な経験からは、単一の使用法の値については少しやり過ぎです。そして、それらは前もってWebComponentでサポートされなければなりません。
伝播:Host
を介したプロパティ継承(@Renatoが述べたとおり)は、IMHOのAPIデザインに沿った完全に正しいパターンです。
:Host
's)のCSSルールは、設計により外側のルールによってオーバーライド可能です:Host
の子、Shadow DOMの内部コンテンツは、デフォルトまたは明示的なルールのいずれかで、:Host
のCSSルールを継承する場合があります。該当する場合は、CSSスタイルシートの挿入を検討する前にこのアプローチを採用することをお勧めします。また、open
モードのみの制限を受けません。
もちろん、このアプローチは次の場合には役立ちません。
:Host
から関連するルールを継承していません:Host
ですべてを支援することはできませんそれでも、私自身の経験から、CSSルールをオーバーライドできることが望ましい単純なコンポーネントは、:Host
を介してルールを伝播する非侵入型パターンから多くの利益を得ることができます。