In (unusual) cases where you want to be able to dynamically change styles often -- e.g. a theme builder app -- adding <style> tags or calling CSSStyleSheet.insertRule() will result in a growing stylesheet, which can have performance and design debugging implications.
My approach only allows a single rule per selector/property combo, clearing any existing on setting any rule. The API is simple and flexible:
function addStyle(selector, rulename, value) {
var stylesheet = getAppStylesheet();
var cssRules = stylesheet.cssRules || stylesheet.rules;
var rule = stylesheet.insertRule(selector + ' { ' + rulename + ':' + value + ';}', cssRules.length);
}
function clearStyle(selector, rulename) {
var stylesheet = getAppStylesheet();
var cssRules = stylesheet.cssRules || stylesheet.rules;
for (var i=0; i<cssRules.length; i++) {
var rule = cssRules[i];
if (rule.selectorText == selector && rule.style[0] == rulename) {
stylesheet.deleteRule(i);
break;
}
}
}
function addStyles(selector, rules) {
var stylesheet = getAppStylesheet();
var cssRules = stylesheet.cssRules || stylesheet.rules;
for (var prop in rules) {
addStyle(selector, prop, rules[prop]);
}
}
function getAppStylesheet() {
var stylesheet = document.getElementById('my-styles');
if (!stylesheet) {
stylesheet = $('<style id="my-styles">').appendTo('head')[0];
}
stylesheet = stylesheet.sheet;
return stylesheet;
}
Usage:
addStyles('body', {
'background-color': 'black',
color: 'green',
margin: 'auto'
});
clearStyle('body', 'background-color');
addStyle('body', 'color', '#333')