O componente HTML da web não usa o estilo DOM sombra
Eu criei um componente da web vanilla ou elemento HTML. Ele apenas exibe dois links.
Para encapsular a coisa, eu uso o DOM sombra. No entanto, não parece estar encapsulado. Na árvore DOM está dentro de # shadow-root, o que é bom.
Por que o componente da web usa o estilo global em vez do estilo que forneci no modelo para meu componente da web?
O texto está vermelho e eu esperava que fosse verde.
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>
Respostas
Embora essa pergunta já tenha uma resposta aceita, mover os filhos de um slot para o shadowRoot não é desejável para a maioria dos casos de uso.
O que você provavelmente deseja fazer é usar o ::slotted()
seletor.
Lembre-se de que os estilos aplicados aos filhos de um slot por meio do ::slotted()
seletor funcionam apenas como estilos "padrão" e ainda podem ser substituídos pelo uso de estilos no DOM claro.
Por exemplo, verifique esta versão editada do seu snippet:
Como você pode ver, desta vez my-el
tenta aplicar uma cor e um estilo de decoração de texto aos <a>
filhos anchor ( ) em qualquer um de seus slots.
No entanto, no dom de luz, temos um a.special
seletor que substitui a cor, então o <a class="special">
será vermelho, não verde
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>
A explicação completa e detalhada está em: :: seletor CSS com slot para filhos aninhados no slot shadowDOM
TL; DR
Seus links estão em lightDOM e, portanto, estilizados por seu DOM (em seu código, o DOM do documento)
Mover os nós de lightDOM para shadowDOM é uma "solução"; mas você não está usando slots então.
Para sua informação, seu código pode ser compactado para:
class MyEl extends HTMLElement {
constructor() {
super().attachShadow({ mode: "open" })
.innerHTML = `<style>a{color:green}</style><slot></slot>`;
}
}
window.customElements.define("my-el", MyEl);
Mais respostas relacionadas a SLOT podem ser encontradas com StackOverflow Search: Custom Elements SLOTs
observe esta linha, você deve mover / copiar elementos para a sombra, por exemplo com:
this.shadow.innerHTML = this.innerHTML + template;
Eu adicionei isso para demonstrar que apenas o estilo embutido será aplicado aos elementos do shadow dom .. então, os links copiados em SD estão usando o seu estilo :)
então o vermelho será GLOBAL
, o verde serão os SHADOW
elementos
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>