CSSStyleSheet.insertRule() method inserts a new CSS rule into the current style sheet, with some restrictions.

More specifically, though insertRule() is exclusively a method of the CSSStyleSheet, it actually inserts the rule into CSSStyleSheet.cssRules, the CSSRuleList therein.

What the rule must contain depends on its type: For rule-sets the rule specifies both the selector and the style declaration. For at-rules, the rule specifies both the at-identifier and the rule content.


stylesheet.insertRule(rule[, index])


A DOMString containing the rule to be inserted, where rule specifies selector and declaration, or at-identifier and rule content.
index Optional
An unsigned integer not greater than stylesheet.cssRules.length representing the position in CSSStyleSheet.cssRules to insert at. In older implementations, this was required. See Browser compatibility for details. The default is 0. 

Return value

The index within the style sheet's rule-list of the newly inserted rule.


CSS stylesheet rule-lists have a number of intuitive and not-so-intuitive restrictions affecting how and where rules can be inserted. Violating these will likely cause an error raised as a DOMException 

  • If index > number of rules in the stylesheet (the CSSRuleList.length), then aborts with IndexSizeError.
  • If rule cannot be inserted at index 0 due to some CSS constraint, then aborts with HierarchyRequestError.
  • If more than one rule is given in the rule parameter, then aborts with SyntaxError
  • If trying to insert an @import at-rule after a style rule, then aborts with HierarchyRequestError.
  • If rule is @namespace at-rule and list has more than just @import at-rules and/or @namespace at-rules, then aborts with InvalidStateError.


Example 1

// push a new rule onto the top of my stylesheet
myStyle.insertRule("#blanc { color: white }", 0); 

Example 2

 * Add a stylesheet rule to the document (may be better practice, however,
 * 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 afford a predictable object iteration order and since CSS is 
 * order-dependent (i.e., it is cascading); those without need of
 * cascading rules could build a more accessor-friendly object-based API.
 * @param {Array} rules Accepts an array of JSON-encoded declarations
 * @example
  ['h2', // Also accepts a second argument as an array of arrays instead
    ['color', 'red'],
    ['background-color', 'green', true] // 'true' for !important rules 
    ['background-color', 'yellow']
function addStylesheetRules (rules) {
  var styleEl = document.createElement('style'),

  // Append style element to head

  // Grab style sheet
  styleSheet = styleEl.sheet;

  for (var i = 0, rl = rules.length; i < rl; i++) {
    var j = 1, rule = rules[i], selector = rules[i][0], propStr = '';
    // If the second argument of a rule is an array of arrays, correct our variables.
    if (Object.prototype.toString.call(rule[1][0]) === '[object Array]') {
      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 to insertRule to standardize insertRule in Internet Explorer 5-8. Bascially, all this polyfill does is, in IE5-8, it suplements insertRule with a function that separates the selector from the rules before sending the arguments to the default native insertRule. 

    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]);

Browser compatibility

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Basic support Yes Yes Yes9 Yes Yes
index is optional60 ? ? ?47 ?
FeatureAndroid webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
Basic support Yes Yes Yes Yes Yes Yes ?
index is optional6060 ? ?47 ? ?

Legacy browser support

  • Internet Explorer - pre v9

    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.

See also