I am trying to move an element from the light DOM to the shadow DOM, but when I do so the styling isn't copying over. I tried to fix this by setting the newElement.style = window.getComputedStyle(elem)
, but this hasn't seemed to work. The styles should be:
.card {
color: #ff0;
font-size: 3rem;
font-weight: 600;
border: 3px solid blueviolet;
background-color: greenyellow;
}
but the styles don't apply and when I print the getComputedStyle()
to console what I see is:
all the values are empty
However, when I loop through the properties of getComputedStyle()
with .getPropertyValue()
like so:
for(let property of style){
console.log(`property: ${property}, value: ${style.getPropertyValue(property)}`);
}
what I get in the console is: the correct values
So I'm confused as to why getComputedStyle()
doesn't contain the values, but using getComputedStyle().getPropertyValue()
returns the correct values. I'm sure I'm missing something obvious, as I couldn't find another post about this anywhere.
Any help would be greatly appreciated, thanks in advance.
EDIT: I've taken the code provided by Danny below and modified it to better show the issue I'm facing:
<style>
.card {
color: yellow;
background: green;
}
</style>
<my-element>
<div class="card">lightDOM reflected to shadowDOM</div>
</my-element>
<script>
customElements.define("my-element", class extends HTMLElement {
constructor(){
super().attachShadow({mode:"open"}).innerHTML = ``;
}
connectedCallback() {
setTimeout(() => { // wait till innerHTML is parsed
let card = this.children[0]; // Get the light DOM Card element
this.shadowRoot.appendChild(card.cloneNode(true)); // Append it to the shadowDOM
let style = window.getComputedStyle(card); // Get style of the Light DOM Card
this.shadowRoot.querySelector('.card').style = style; // Set the ShadowDOM card style equal to the Light DOM Style
console.log(style);
console.log(style.color); // yellow = rgb:255,255,0
console.log(style.background); // green = rgb:0,128,0
card.remove(); // Remove the card from the Light DOM to prevent duplication
})
}
})
</script>
Notice that the styling above doesn't apply even though it seems to be exactly as the docs specify: "The returned object is the same CSSStyleDeclaration type as the object returned from the element's style property. However, the two objects have different purposes:
From MDN Documentation:
The
Window.getComputedStyle()
method returns an object containing the values of all CSS properties of an element, after applying active stylesheets and resolving any basic computation those values may contain. Individual CSS property values are accessed through APIs provided by the object, or by indexing with CSS property names.
It's stated that you need to use API functions, such as getPropertyValue()
to get the value of it.
Ref: https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
If you want to print all of the CSS styles from a specific element you may just iterate all the attributes like this:
function dumpCSSText(element){
var s = '';
var o = getComputedStyle(element);
for(var i = 0; i < o.length; i++){
s+=o[i] + ': ' + o.getPropertyValue(o[i])+';\n';
}
return s;
}
var e = document.querySelector('.card');
console.log(dumpCSSText(e));
.card {
color: #ff0;
font-size: 3rem;
font-weight: 600;
border: 3px solid blueviolet;
background-color: greenyellow;
}
<div class="card"></div>