ShadyCSSポリフィルがEdgeでCSSを適切に処理しない


8

サードパーティのWebサイト用のウィジェットを構築しています。シャドウDOMを使用して、CSSが私たちのWebサイトに干渉しないようにしています。私が使用していますShadyDOMShadyCSSそれがエッジで動作させるためpolyfillsをし、IEが、私が期待するように、影のDOMのためのCSSを変換されていません。

例:

<!DOCTYPE html>
<html>
	<head>
		<title>Shadow DOM test</title>
	</head>
	<body>
		<div id="container">container is here</div>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.3.0/webcomponents-bundle.js"></script>
		<script>
			const shadow = document.getElementById("container").attachShadow({ mode: "open" });
			const style = document.createElement("style");
			style.innerHTML = `
				:host .stuff {
					background: #ff00ff;
				}
			`;
			shadow.appendChild(style);
			const div = document.createElement("div");
			div.classList.add("stuff");
			div.innerHTML = "stuff inside shadow dom";
			shadow.appendChild(div);
		</script>
	</body>
</html>

Chrome(ネイティブでシャドウDOMをサポート)では、stuffdivの背景がピンクになります。しかし、Edge(これはシャドウDOMをネイティブではサポートしていません)では、「シャドウDOMの内部にあるもの」というテキスト(スクリプトが実行され、ShadyDOM関数が機能したことを意味します)は表示されますが、ピンク色の背景は表示されません。

なんでこんなことが起こっているの?ShadyCSS READMEの例のようにカスタム要素を使用する代わりに、プレーンな古いdivにシャドウルートをアタッチしていますが、それは重要ですか?もしそうなら、どのようにこれを機能させることができますか?私は大きな既存のアプリに取り組んでいて、一度に多くの変更を加えたくないので、私が思いつくのではなくdiv、すでに使用している標準のHTML要素(s、buttonsなど)を使用することを強くお勧めします独自の要素またはテンプレート。ただし、大きな変更を加えることなく、簡単に行うことができる場合は、テンプレートやカスタム要素を検討します。


style要素をdivシャドウルートの代わりに内部に直接style追加する、内部を追加した後に要素を追加する、追加した後に要素のdivを設定するinnerHTMLなど、いくつかのことを試しましstyleた。しかし、それらのどれも助けにはなりませんでした。
エリアスザマリア2019

:hostCSSセレクターからを削除すると、スタイルが適用されます。しかし、それらはシャドウルートの外にあるものにも適用されます。
エリアスザマリア2019

私はまた、のようなものを試してみましたShadyCSS.styleElement(element)ShadyCSS. styleSubtree(element)、彼らは動作しませんでした。
エリアスザマリア2019年

テンプレートを使用して作成したカスタム要素のスタイルをポリフィルに設定することはできましたが、アプリでそれを行うには多くの変更と再設計が必要になるため、そのようなことは避けたいと思います。
エリアスザマリア

これが誰にとっても便利な場合:私のアプリはPreactを使用しています。CSSをサードパーティのCSSから分離するために、より高次のコンポーネントを使用しています(他の方法でCSSを妨害することになります)。私たちのものをiframeに入れstyle、適切な場所にタグを配置して寸法を適切に調整するいくつかのトリックを実行することで機能します。レンダリングが遅く、扱いにくいので、シャドウDOMを使用するように変更しました。現在では、Microsoft以外のすべてのブラウザで美しく動作します。EdgeとIEでポリフィルを使用して機能させようとしていますが、機能しません。
エリアスザマリア2019年

回答:


7

ShadyCSSを使用

:host CSS疑似要素はEdgeでは認識されていません。

これを機能させるにShadyCSS.prepareTemplate()は、:hostをカスタム要素の名前に置き換え、スタイルをすべてのページに適用されるグローバルスタイルとして定義する必要があります。

EdgeにはShadow DOMがないことを思い出してください。偽の/ポリフィルされたShadow DOMを持つCSSには境界/スコープがありません。

あなたのケースShadyCSS.prepareTemplate( yourTemplate, 'div' )では、以下の例のように使用できます:

ShadyCSS.prepareTemplate( tpl, 'div' )
container.attachShadow( { mode: "open" } )
         .appendChild( tpl.content.cloneNode(true) )
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.3.0/webcomponents-bundle.js"></script>

<template id=tpl>
    <style>
    :host .stuff {
       background: #ff00ff;
     }
     </style>
    <div class=stuff>stuff inside shadow dom</div>
</template>

<div id=container>container is here</div>

注:ポリフィルは:hostをdivに置き換えてグローバルスタイルとして追加するため、と一致する別のHTMLコードパーツがある場合、いくつかの副作用が発生する可能性がありますdiv .stuff


ShadyCSSなし

ShadyCSSはカスタム要素用に設計されましたが、実際には標準要素用ではありません。ただし、ポリフィルからインスピレーションを得て、偽の(ポリフィルされた)Shadow DOMのスタイルプロパティを明示的に作成する必要があります。あなたの場合は次のように置き換え:hostてくださいdiv#containter

container.attachShadow( { mode: "open" } )
         .appendChild( tpl.content.cloneNode(true) )
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.3.0/webcomponents-bundle.js"></script>

<template id=tpl>
    <style>
    div#container .stuff { 
       background: #ff00ff;
     }    
    :host .stuff {
       background: #ff00ff;
     }
     </style>
    <div class=stuff>stuff inside shadow dom</div>
</template>

<div id=container>container is here</div>


ご回答ありがとうございます。私は自分のアイデアを試すのに忙しい。私はあなたのことを試してみて、チャンスがあればそれを受け入れるか賛成することを検討します。チャンスはおそらく明日になるでしょう。
エリアスザマリア

この答えは私にとても感謝しました!
カリポップ

見栄えはいいですが、テンプレートの内容を(簡単かつ現実的に)常に(さまざまな理由で)divのコンテンツを変更しようとしているPreact(またはReact)アプリで機能させることはできますか?シャドウDOMを適切なタイミングで何らかの方法で変更する必要がありますよね?
エリアスザマリア2019年

@EliasZamaria申し訳ありませんが、私はReactの専門家ではありませんが、Shadow DOM(github.com/Wildhoney/ReactShadowなど)で使用することを知っています。ユースケースによっては、MutationObserverを使用してDOMの変更を検出する必要があるかもしれません。
Supersharp

@Supersharp回答ありがとうございます。突然変異オブザーバーはクールに見えますが、私がユースケースでそれらを使用するのに努力する価値はないと思います(EdgeとIEを使用するユーザーの8%程度に十分にシャドウDOMをエミュレートします)。
エリアスザマリア2019年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.