The CSSStyleSheet.insertRule() method inserts a new CSS rule into the current style sheet, with some restrictions.
Note: Although insertRule() is exclusively a method of CSSStyleSheet, it actually inserts the rule into CSSStyleSheet.cssRules — its internal CSSRuleList.
stylesheet.insertRule(rule[, index])
A DOMString containing the rule to be inserted. What the inserted rule must contain depends on its type:
stylesheet.cssRules.length, representing the newly inserted rule's position in CSSStyleSheet.cssRules. The default is 0. (In older implementations, this was required. See Browser Compatibility for details.)The newly inserted rule's index within the stylesheet's rule-list.
CSS has intuitive and not-so-intuitive restrictions affecting where rules can be inserted. Violating them will likely raise a DOMException .
CSSRuleList.length, then aborts with IndexSizeError.0 due to some CSS constraint, then aborts with HierarchyRequestError.SyntaxError.@import at-rule after a style rule, then aborts with HierarchyRequestError.@namespace and the rule-list has more than just @import at-rules and/or @namespace at-rules, then aborts with InvalidStateError.// push a new rule onto the top of my stylesheet
myStyle.insertRule("#blanc { color: white }", 0);
/**
* Add a stylesheet rule to the document (it may be better practice
* to dynamically change classes, so style information can be kept in
* genuine stylesheets and avoid adding extra elements to the DOM).
* Note that an array is needed for declarations and rules since ECMAScript does
* not guarantee a predictable object iteration order, and since CSS is
* order-dependent.
* @param {Array} rules Accepts an array of JSON-encoded declarations
* @example
addStylesheetRules([
['h2', // Also accepts a second argument as an array of arrays instead
['color', 'red'],
['background-color', 'green', true] // 'true' for !important rules
],
['.myClass',
['background-color', 'yellow']
]
]);
*/
function addStylesheetRules (rules) {
var styleEl = document.createElement('style');
// Append <style> element to <head>
document.head.appendChild(styleEl);
// Grab style element's sheet
var styleSheet = styleEl.sheet;
for (var i = 0; i < rules.length; i++) {
var j = 1,
rule = rules[i],
selector = rule[0],
propStr = '';
// If the second argument of a rule is an array of arrays, correct our variables.
if (Array.isArray(rule[1][0])) {
rule = rule[1];
j = 0;
}
for (var pl = rule.length; j < pl; j++) {
var prop = rule[j];
propStr += prop[0] + ': ' + prop[1] + (prop[2] ? ' !important' : '') + ';\n';
}
// Insert CSS Rule
styleSheet.insertRule(selector + '{' + propStr + '}', styleSheet.cssRules.length);
}
} | Specification | Status | Comment |
|---|---|---|
| CSS Object Model (CSSOM) The definition of 'CSSStyleSheet.insertRule' in that specification. | Working Draft | No change from Document Object Model (DOM) Level 2 Style Specification. |
| Document Object Model (DOM) Level 2 Style Specification The definition of 'CSSStyleSheet.insertRule' in that specification. | Obsolete | Initial definition |
The below polyfill will correct the input of the arguments of insertRule to standardize them in Internet Explorer 5–8. It supplements insertRule with a function that separates the selector from the rules before sending the arguments to the default native insertRule.
(function(Sheet_proto){
var originalInsertRule = Sheet_proto.insertRule;
if (originalInsertRule.length === 2){ // 2 mandatory arguments: (selector, rules)
Sheet_proto.insertRule = function(selectorAndRule){
// First, separate the selector from the rule
a: for (var i=0, Len=selectorAndRule.length, isEscaped=0, newCharCode=0; i !== Len; ++i) {
newCharCode = selectorAndRule.charCodeAt(i);
if (!isEscaped && (newCharCode === 123)) { // 123 = "{".charCodeAt(0)
// Secondly, find the last closing bracket
var openBracketPos = i, closeBracketPos = -1;
for (; i !== Len; ++i) {
newCharCode = selectorAndRule.charCodeAt(i);
if (!isEscaped && (newCharCode === 125)) { // 125 = "}".charCodeAt(0)
closeBracketPos = i;
}
isEscaped ^= newCharCode===92?1:isEscaped; // 92 = "\\".charCodeAt(0)
}
if (closeBracketPos === -1) break a; // no closing bracket was found!
/*else*/ return originalInsertRule.call(
this, // the sheet to be changed
selectorAndRule.substring(0, openBracketPos), // the selector
selectorAndRule.substring(closeBracketPos), // the rule
arguments[3] // the insert index
);
}
// works by if the char code is a backslash, then isEscaped gets flipped (XOR-ed by
// 1), and if it is not a backslash then isEscaped gets XORed by itself, zeroing it
isEscaped ^= newCharCode===92?1:isEscaped; // 92 = "\\".charCodeAt(0)
}
// Else, there is no unescaped bracket
return originalInsertRule.call(this, selectorAndRule, "", arguments[2]);
};
}
})(CSSStyleSheet.prototype);
| Desktop | ||||||
|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | |
| Basic support | Yes | Yes | Yes | 9 | Yes | Yes |
index is optional |
60 | ? | ? | ? | 47 | ? |
| Mobile | |||||||
|---|---|---|---|---|---|---|---|
| Android webview | Chrome for Android | Edge Mobile | Firefox for Android | Opera for Android | iOS Safari | Samsung Internet | |
| Basic support | Yes | Yes | Yes | Yes | Yes | Yes | ? |
index is optional |
60 | 60 | ? | ? | 47 | ? | ? |
addRule(selector, rule [, index]); — Example: addRule('pre', 'font: 14px verdana'); // add rule at end
Also note the non-standard removeRule() and .rules instead of deleteRule() and .cssRules respectively.
© 2005–2018 Mozilla Developer Network and individual contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule