Is there a native API which can update the CSS variables scoped under a particular CSS class(or even any other complex CSS selector)predefined in a stylesheet? The question can be generalized for not just CSS variables but other CSS properties as well, i.e whether class specific CSS properties can be updated without targeting a specific HTML element, but by targeting the class definition itself.
Please find below the code snippets which demonstrates an example scenario. You can also find comments in the code to as to what I believe is happening/I am doing on specific lines.
var toggle = true;
function changeColor() {
document.documentElement.style.setProperty('--bg-color', toggle ? 'green' : 'red');
// this works for the "outer" div since there we receive global value(value defined in :root) of --bg-color
toggle = !toggle;
// here I want to also change the scoped value of --bg-color for "inner-primary" and "inner-secondary"
// currently I can do this by doing:
document.querySelectorAll('.inner-primary').forEach(ele => ele.style.setProperty('--bg-color', toggle ? 'blue' : 'yellow'))
document.querySelectorAll('.inner-secondary').forEach(ele => ele.style.setProperty('--bg-color', toggle ? 'yellow' : 'blue' ))
// another way I can see is: we dynamically insert a style tag, but this feels very awkward and can quickly get out of hand on multiple iterations
}
:root {
--bg-color: red;
}
body {
margin: 0;
}
.outer {
width: 100vw;
height: auto;
min-height: 100vh;
text-align: center;
background-color: var(--bg-color); /* receives value from :root */
}
.inner-primary,
.inner-secondary {
width: 100px;
height: 100px;
/* received scoped value from .inner-primary or .inner-secondary defined below*/
background-color: var(--bg-color);
border: 1px solid black;
margin: auto;
margin-bottom: 10px;
}
.inner-secondary {
--bg-color: yellow;
}
.inner-primary {
--bg-color: blue;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Testing</title>
</head>
<body>
<div class="outer">
<div class="inner-primary"></div>
<div class="inner-secondary"></div>
<div class="inner-primary"></div>
<div class="inner-secondary"></div>
<button onclick="changeColor()">Change Color</button>
</body>
</html>
Please try running this to get a full idea of intended effect. You can click "Change Color" button at the bottom to see the effects in action.
To get the intended overriding for CSS variable --bg-color for classes inner-primary and inner-secondary, I had to use querySelectorAll with the required CSS selector(in this case just a class name) and iteratively set the CSS variable for each individual element found.
By nature of how CSS gets read by the browser, feels like the other solution to this is to dynamically insert a style element tag into the DOM, with the required CSS variable update, scoped under the required class name(or any other required selector).. But this feels awkward and can quickly get out of hand if we don't implement some system to reuse the same style tag and not insert new ones during each toggle.
Is there any other way to do this? Any native API which can solve this without having to access individual elements or without inserting style tags dynamically..?