ShadowCSS polyfill неправильно обрабатывает CSS в Edge - PullRequest
8 голосов
/ 30 сентября 2019

Я создаю виджет для сторонних веб-сайтов, используя теневой DOM, чтобы их CSS не мешал нашему. Я использую полифилы ShadyDOM и ShadyCSS , чтобы заставить его работать в Edge и IE, но это не преобразует CSS для теневого DOM, как я ожидал.

Пример:

<!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) div stuff имеет розовый фон, как я и ожидал. Но в Edge (который изначально не поддерживает shadow DOM), я вижу текст «stuff in shadow dom» (что означает, что мой скрипт запущен, и функции ShadyDOM работают), но я не вижу розовый фон.

Почему это происходит? Я присоединяю теневой корень к простому старому div, вместо того чтобы использовать пользовательские элементы, как это делает пример из README ShadyCSS, но имеет ли это значение? Если да, как я могу заставить это работать? Я работаю над большим существующим приложением и не хочу вносить слишком много изменений одновременно, поэтому Я бы настоятельно предпочел использовать стандартный HTMLэлементы, которые я уже использую (div s, button s и т. д.) вместо того, чтобы придумывать свои собственные элементы или шаблоны , хотя я хотел бы рассмотреть шаблоны и / или пользовательские элементы, если это возможносделано легко, без необходимости вносить много больших изменений.

1 Ответ

7 голосов
/ 03 октября 2019

С ShadyCSS

:host Псевдоэлемент CSS не известен в Edge.

Чтобы заставить его работать, вы должны использовать ShadyCSS.prepareTemplate(), который заменит: host по имени пользовательского элемента и определите стиль как глобальный стиль, который будет применяться ко всей странице.

Помните, что в Edge нет Shadow DOM: нет границ / областей действия для CSS с поддельным / заполненным Shadow DOM.

В вашем случае вы можете использовать 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>
...