I am attempting to modify the styles of two custom HTML elements, "output-screen" and "custom-calculator" using shadow DOM.
When I try to do so by attaching a shadow DOM as shown below, the styles are not applied. Any ideas what I'm doing wrong?
<custom-calculator id="calculator">
<output-screen></output-screen>
</custom-calculator>
<script>
var o = Object.create(HTMLElement.prototype);
var oElement = document.registerElement('output-screen', {
prototype: o
});
var c = Object.create(HTMLElement.prototype);
var cElement = document.registerElement('custom-calculator', {
prototype: c
});
var calc = document.querySelector('#calculator')
calc.attachShadow({ mode: 'open' });
calc.shadowRoot;
calc.shadowRoot.innerHTML = `
<style>
output-screen{
display:inline-block;
background-color:orange;
width:50%;
height:100vh;
}
custom-calculator {
display:inline-block;
background-color:grey;
width:100%;
height:100vh;
vertical-align:top;
}
</style>
`;
</script>
In order to style the element that hosts the Shadow DOM, here <custom-calculator>
, you must use de :host
pseudo-class (instead of custom-calculator
which is unknown inside the Shadow DOM).
:host {
display:inline-block;
background-color:grey;
width:100%;
height:100vh;
vertical-align:top;
}
Because the Shadow DOM will replace/recover the normal DOM tree (here <output-screen>
), you'll have to use <slot>
to insert/reveal it in the Shadow DOM.
calc.shadowRoot.innerHTML = `
<style>
...
</style>
<slot></slot>`
Then, in order to style what is revealed by/in the <slot>
element, you mus use the ::slotted()
pseudo-element:
::slotted( output-screen ){
display:inline-block;
background-color:orange;
width:50%;
height:100vh;
}
Live example:
var calc = document.querySelector('#calculator')
calc.attachShadow({mode: 'open'});
calc.shadowRoot.innerHTML = `
<style>
:host {
display:inline-block;
background-color:grey;
width:100%;
height:100vh;
vertical-align:top;
}
::slotted( output-screen ){
display:inline-block;
background-color:orange;
width:50%;
height:100vh;
}
</style>
<slot></slot>`;
<custom-calculator id="calculator">
<output-screen></output-screen>
</custom-calculator>