Lots of answers on how to get/set "root" CSS variables but none that I've found on how to get/set NON root CSS variables.
NOTE: This is NOT answer: https://stackoverflow.com/a/36088890/104380 That answer only handles root variables and or variables on elements, not on classes
Also: These are not answers (from: https://www.google.com/search?q=get%2Fset+css+variables). Checked the first page of links. All of them only handle root variables. I'm trying to deal with non-root variables.
.foo {
--fg-color: red;
}
.bar {
--fg-color: blue;
}
div {
color: var(--fg-color);
}
<div class="foo">foo</div>
<div class="bar">foo</div>
How do you get someFunctionToGetCSSVariable('.foo', '--fg-color') (yes, I made that up). The point is I want to get/set the --fg-color variable on the .foo CSS rule. Whatever the solution is, getting the value it should return 'red' or '#FF0000') and how do you set it to something else?
I think what OP tries to do is not to change the all elements of that certain class, but to change the class itself, there is a difference. What you need (if I understood well) is actually cssRules change on the certain class. I've created a quick (and dirty) snippet of how to search the cssRules and change the CSS properties in it (including custom one):
<html>
<head>
<style>
.foo {
--fg-color: red;
}
</style>
</head>
<body>
<div class="foo">lorem ipsum</div>
<script>
window.onload = function() {
rules = document.styleSheets[0].cssRules
for (var r in rules) {
if (rules[r].selectorText == ".foo") {
rules[r].style.setProperty('--fg-color', 'blue');
alert('hi');
break;
}
}
};
</script>
</body>
</html>
You could make use of the fact that we have cascading style sheets.
It depends on exactly what your structure is of course, (e.g. are there style elements buried in body?).
For the simple case you could add another stylesheet onto the bottom of the head element.
<!doctype html>
<html>
<head>
<style>
.foo {
--fg-color: red;
}
.bar {
--fg-color: blue;
}
div {
color: var(--fg-color);
}
</style>
</head>
<body>
<div class="foo">foo</div>
<div class="bar">foo</div>
<button>Click me</button>
<script>
const button = document.querySelector('button');
button.addEventListener('click', function () {
const head = document.querySelector('head');
const style = document.createElement('style');
style.innerHTML = '.foo { --fg-color: lime; }';
head.appendChild(style);
button.style.display = 'none';
});
</script>
</body>
</html>
Of course, it could get messy if this happens more than once. You'd want to remember that you'd added a style sheet and get rid of it before adding another one, or alter it in situ, depending on exactly what the situation is. And if there is styling scattered in the body you'll have to add the stylesheet to the bottom of that.
Looks like I have to iterate through all the stylesheets and find the rule. Here's one try.
function getCSSRuleBySelector(selector) {
for (let s = 0; s < document.styleSheets.length; ++s) {
const rules = document.styleSheets[s].cssRules;
for (let i = 0; i < rules.length; ++i) {
const r = rules[i];
if (r.selectorText === selector) {
return r;
}
}
}
}
function setCSSVariableBySelector(selector, varName, value) {
const rule = getCSSRuleBySelector(selector);
rule.style.setProperty(varName, value);
}
function getCSSVariableBySelector(selector, varName) {
const rule = getCSSRuleBySelector(selector);
return rule.style.getPropertyValue(varName);
}
console.log('was:', getCSSVariableBySelector('.foo', '--fg-color'));
setCSSVariableBySelector('.foo', '--fg-color', 'green');
.foo {
--fg-color: red;
}
.bar {
--fg-color: blue;
}
div {
color: var(--fg-color);
}
<div class="foo">foo</div>
<div class="foo">foo</div>
<div class="foo">foo</div>
<div class="bar">bar</div>
<div class="bar">bar</div>