The value of the background shorthand property expands incorrectly when trying to call HTMLElement.style
P粉269530053
2023-09-03 21:10:48
<p>In the element's style, I have some inline CSS declarations, including a shorthand declaration for the background</p>
<pre class="brush:php;toolbar:false;"><style>
:root{
--bg-white: rgba(255, 255, 255, 0);
}
</style>
<div style="background: var(--bg-white); ... "></div></pre>
<p>But when iterating over HTMLElement.style, the shorthand properties look like they are incorrectly expanded</p>
<pre class="brush:php;toolbar:false;">for (const declaration of Array.from(target.style)) {
const value = target.style.getPropertyValue(declaration)
console.log(`${declaration}: ${value}`)
}</pre>
<p>This should print out <code>background-color: var(--bg-white)</code> according to the HTMLElement.style documentation on MDN, but I get <code>background-color: ' '</code> </p>
<blockquote>
<p>Expanded abbreviation properties. If style="border-top: 1px Solid black" is set, the normal properties (border-top-color, border-top-style and border-top-width) are set. </p>
</blockquote>
<p>Has anyone encountered this situation? </p>
Problem using
Array.from(target.style)to obtain the default iterator oftarget.style. It does not include background properties. According to the specification, shorthand properties have been extended to its various parts.Everything is explained in the code.
Thanks to @t.niese for the tip in the comments.
<div id="test" style="background: var(--bg-white);">Test</div> <script> const target = document.querySelector('#test'); // style is itarable console.log(target.style[Symbol.iterator]); // but doesn't include background in the iterator console.log(...target.style); // but background is iterable! console.log(Object.getOwnPropertyDescriptor(target.style, 'background')); // we can see it in Object.keys console.log(Object.keys(target.style).filter(name => name === 'background')); // so we can iterate it anyway for(const k in target.style){ if(k === 'background'){ console.log(target.style[k]); } } // Object.entries works too console.log(Object.entries(target.style).filter(([name]) => name === 'background')); // or access directly console.log(target.style.getPropertyValue('background')); console.log(target.style.background); </script>If you use
HTMLElement.style, it will return what is applied directly (rather than calculated) via thestyleattribute.In this case, the browser has no way of knowing what the
So if you for example havevar(...)in background: var(--bg-white);will parse and will Whichbackground-...properties are included (the contents of the variable will be placed where thevar(...)statement is and the resulting value will be parsed.--bg-white: content-box Radial-gradient(crimson, skyblue);
then your--bg-whitewill actually affect Multiple properties.