Here's an embarrassingly simple trick I've been using for dynamically manipulating CSS class rules, which dodges the complications (like parsing through the rules to locate the one you need, as noted by the expected answer), and even provides some extra flexibility for free.
(A side-note: the prev. attempt of adding this answer got instanty downvoted, within seconds, without feedback, by one of the few auto-notification targets of this page. I'm not sure the short knee-jerk reaction time was enough to see why this is a reliable solution that covers the OP's use case well, nevertheless I've rephrased it, guessing the narrative may have somehow been the trigger. Or the lack of semicolons (which I've now added for him). Or the lack of unnecessary curly braces (also added). Or the lack of notes on non-effects (added). Or not using a sufficiently complicated method (won't fix, even simplified the code yet some more). I'm sure he'll hit again anonymously, but still retry, because this is a clean & robust technique worth using.)
NOTE: This approach assumes you have sufficient control over the styling of the page to make sure the same class rule would not get created by a different method. (And it expects the HEAD
element to exist.)
(One potential cost of this approach could be re-rendering on innerHtml
, but since we are changing CSS anyway, repaint is imminent. Also, innerHtml
is done to a non-displayed element, so browsers could optimize it out even if it otherwise mattered.)
OK. Since you can have any number of STYLE
elements, it's perfectly fine to wrap your dynamic class in its own separate one. Um, that's it. :) Then, add an id
or, even better*, a class
attribute to the wrapper STYLE
, so you can practically access and manipulate your class rule as if it was a DOM element. Just make sure it's wrapped in <style class="..."> ... </style>
, when adding/replacing.
Bonus: you can also group multiple related rules and replace them all at once this way, if you wish (with trivial modifications):
function replace_class(classname, block) {
// Remove old:
var s = document.head.querySelector("style." + classname);
if (s) { document.head.removeChild(s); }
// Just delete?
if (!block) { return; }
// Add new:
s = document.createElement("style");
s.className = classname;
s.innerHTML = ("." + classname + block); // <style class="classname">.classname{...}</style>
document.head.appendChild(s);
}
Then, to update: replace_class("menu", "{font-size: 8px;}")
.
Or delete: replace_class("menu", null)
.
* Since CSS applies to every element, you may wonder why won't STYLE
itself get unexpectedly rendered, if your new class had a display: ...
with something else than none
. Well, it would, if it was put in the BODY
! But, since we add it to HEAD
, rendering is skipped (unless, of course, you opt to display HEAD
, too). Or, you could also use id
instead, but then you had to invent/use proper scoping/prefixing, and why would you want that if it can be spared? (And I also like the subtle cheekiness of setting class
when it's a class wrapper anyway...)