150

I've read conflicting information regarding Internet Explorer's silly CSS limits. I am (think I am) understanding that you can only have 31 <style> and <link> tags (combined), and that each sheet can have up to 31 @import-s (so 31 <link>-s, each to 31 @import-s is fine, albeit insane).

However, the 4095 rule is less clear - is this 4095 rules per document, or per sheet? For instance, can I <link> to two stylesheets, each with 4000 rules, and have it work, or will this break the limit?

3rd party edit 2018

On this msdn blog post stylesheet-limits-in-internet-explorer further information is given.

surfmuggle
  • 4,724
  • 6
  • 38
  • 68
Barg
  • 2,848
  • 7
  • 23
  • 27
  • 1
    It looks like the 4095 limit is per document according to http://www.habdas.org/2010/05/30/msie-4095-selector-limit/ and there is also a link to a test page you could try yourself – andyb Mar 28 '12 at 11:52
  • Why would you need more than 30 stylesheets on a single page anyway? Why would you need 4,000 rules? Even my most complex pages barely get over 1,000 nodes, so you'd have to have over 4 rules per node average to reach the limit... – Niet the Dark Absol Mar 28 '12 at 11:52
  • @Kolink some (bad) content management systems use templates which can lead to many CSS files being included. Unfortunately, I've seen the 31 ` – andyb Mar 28 '12 at 11:56
  • @Kolink - I'm componentising my web application. In my current attempt, 30 components = 30 (tiny) stylesheets, plus the other usual suspects such as normalize.css. In other words, I'm probably implementing something similar to what andyb refers to as 'bad'. :P – Barg Mar 28 '12 at 12:14
  • I'm making my site out of components too, but each page clearly defines which components it needs and imports them. Perhaps you're loading components you don't need, or perhaps your components are too specific and you should group some together - I can't really judge without knowing more. – Niet the Dark Absol Mar 28 '12 at 12:19
  • If you're interested, I'm using requirejs to load these 'components', which themselves consists of Javascript, HTML, and CSS. It's all dynamically loaded. Components are small things like toolbars, or big things such as an user input form (which can also be built from other components). This will be the basis of a large web application, and I'm keen to keep these components small and simple to make it more manageable. Unfortunately, the IE CSS limitations were a bit of a setback to this approach, but I think I can now work around it. – Barg Mar 28 '12 at 12:31

7 Answers7

222

Referring the following from Microsoft:

The rules for IE9 are:

  • A sheet may contain up to 4095 selectors (Demo)
  • A sheet may @import up to 31 sheets
  • @import nesting supports up to 4 levels deep

The rules for IE10 are:

  • A sheet may contain up to 65534 selectors
  • A sheet may @import up to 4095 sheets
  • @import nesting supports up to 4095 levels deep

Testing the 4095 rule by sheet limit

By way of confirmation, I've created a gist with 3 files. One HTML, and two CSS files.

  • The first file contains 4096 selectors and means that its final selector doesn't get read in.
  • The second file (4095.css) has one less selector, and gets read in, and works perfectly in IE (even though its already read another 4095 selectors from the previous file.
Rycochet
  • 2,690
  • 1
  • 19
  • 35
isNaN1247
  • 17,115
  • 12
  • 66
  • 114
  • 2
    It's actually those same two links that have me confused. The KB says "All style rules after the first 4,095 rules are not applied.", which to me implies that it is per-page, the other link says "A sheet may contain up to 4095 rules", which implies that it is per-sheet. – Barg Mar 28 '12 at 11:54
  • After following a few links provided in the comments, I came across http://blesscss.com/ To quote the website, it works by "Keep[ing] the number of selectors in a single file below the limit by splitting your CSS over multiple stylesheets". So it looks to me that the limitation is 4095 rules per sheet after all. – Barg Mar 28 '12 at 12:17
  • @Barg - I can see where your confusion comes from on this - by way of clarifying, I've uploaded a test that you can try out with IE - https://gist.github.com/2225701 – isNaN1247 Mar 28 '12 at 12:25
  • 2
    Thanks very much - that has confirmed that it is per-sheet, not per-page. – Barg Mar 28 '12 at 12:34
  • 30
    It should be noted that the 4095 limit applies to ***selectors***, not **rules**. – Christopher Cortez Jul 17 '13 at 15:10
  • 1
    just for clarification: would the following line count as one "selector", or two? div.oneclass, div.anotherstyle {color: green}; – anthony Nov 05 '13 at 15:44
  • 2
    @anthony, two selectors, one rule. – squidbe May 30 '14 at 20:50
  • 1
    The example gist does not clarify whether the issue is number of selectors, rulesets, or rules. I forked the example gist to put this issue to bed [here](https://gist.github.com/ericandrewlewis/8c850adb4d779aa42e13) - the limit is number of selectors, not number of rules or rulesets. – Eric Andrew Lewis Dec 01 '14 at 16:26
  • Hilariously I recently had a problem where, after making a large app, I tried to minify the CSS and saw that rules were not being applied after a certain point. Turned out that Bootstrap 3.2 + fontawesome + my own CSS was more than 4095 selectors when minified and combined lol – Sammaye Jan 07 '15 at 13:02
116

A javascript script to count your CSS rules:

function countCSSRules() {
    var results = '',
        log = '';
    if (!document.styleSheets) {
        return;
    }
    for (var i = 0; i < document.styleSheets.length; i++) {
        countSheet(document.styleSheets[i]);
    }
    function countSheet(sheet) {
        if (sheet && sheet.cssRules) {
            var count = countSelectors(sheet);

            log += '\nFile: ' + (sheet.href ? sheet.href : 'inline <style> tag');
            log += '\nRules: ' + sheet.cssRules.length;
            log += '\nSelectors: ' + count;
            log += '\n--------------------------';
            if (count >= 4096) {
                results += '\n********************************\nWARNING:\n There are ' + count + ' CSS rules in the stylesheet ' + sheet.href + ' - IE will ignore the last ' + (count - 4096) + ' rules!\n';
            }
        }
    }
    function countSelectors(group) {
        var count = 0;
        for (var j = 0, l = group.cssRules.length; j < l; j++) {
            var rule = group.cssRules[j];
            if (rule instanceof CSSImportRule) {
                countSheet(rule.styleSheet);
            }
            if (rule instanceof CSSMediaRule) {
                count += countSelectors(rule);
            }
            if( !rule.selectorText ) {
                continue;
            }
            count += rule.selectorText.split(',').length;
        }
        return count;
    }

    console.log(log);
    console.log(results);
};
countCSSRules();
mtyaka
  • 8,246
  • 1
  • 35
  • 40
EpokK
  • 37,670
  • 8
  • 57
  • 67
  • 2
    You are a saint for providing this. I had a bug that I couldn't locate locally, and due to our asset minification in prod, it was not possible to track down what was going wrong. I had a feeling we were over IE's selector limit, and your script found it for me. Thank you so much! – robabby Mar 13 '14 at 19:30
  • 9
    It is worth noting that you should not run this script in IE, since it will never emit the warning. – user123444555621 Apr 09 '14 at 10:48
  • 1
    Thank you for the script. It helped me debug a different error – Jdahern May 06 '14 at 22:56
  • 4
    This script is inaccurate. You should include a branch for `@media` rules, see https://stackoverflow.com/a/25089619/938089. – Rob W Aug 01 '14 at 22:54
  • 1
    great script. keep in mind that if the stylesheets are from a different domain than the webpage, you will get null value for sheet.cssRules – CodeToad Jan 05 '15 at 12:53
  • I use this script everytime I have this problem - thank you – James Westgate Mar 31 '16 at 08:43
  • The cross domain issue makes this less useful for me on a production website. – RobW Jan 17 '17 at 18:54
  • Great code! In my case, as @CodeToad said, I had to insert `if(document.styleSheets[i].href != null && document.styleSheets[i].href.indexOf(location.hostname) !== -1 )` to check only the files I owned. – Giovan Cruz Feb 06 '19 at 17:00
34

I don't have enough rep to comment on the above similar snippet, but this one counts the @media rules. Drop it in Chrome console.

function countCSSRules() {
    var results = '',
        log = '';
    if (!document.styleSheets) {
        return;
    }
    for (var i = 0; i < document.styleSheets.length; i++) {
        countSheet(document.styleSheets[i]);
    }
    function countSheet(sheet) {
        var count = 0;
        if (sheet && sheet.cssRules) {
            for (var j = 0, l = sheet.cssRules.length; j < l; j++) {
                if (!sheet.cssRules[j].selectorText) {
                    if (sheet.cssRules[j].cssRules) {
                        for (var m = 0, n = sheet.cssRules[j].cssRules.length; m < n; m++) {
                            if(sheet.cssRules[j].cssRules[m].selectorText) {
                                count += sheet.cssRules[j].cssRules[m].selectorText.split(',').length;
                            }
                        }
                    }
                }
                else {
                    count += sheet.cssRules[j].selectorText.split(',').length;
                }
            }
 
            log += '\nFile: ' + (sheet.href ? sheet.href : 'inline <style> tag');
            log += '\nRules: ' + sheet.cssRules.length;
            log += '\nSelectors: ' + count;
            log += '\n--------------------------';
            if (count >= 4096) {
                results += '\n********************************\nWARNING:\n There are ' + count + ' CSS rules in the stylesheet ' + sheet.href + ' - IE will ignore the last ' + (count - 4096) + ' rules!\n';
            }
        }
    }
    console.log(log);
    console.log(results);
};
countCSSRules();

source: https://gist.github.com/krisbulman/0f5e27bba375b151515d

krisbulman
  • 525
  • 5
  • 12
15

According to a page on the MSDN IEInternals blog entitled Stylesheet Limits in Internet Explorer the limits shown above (31 sheets, 4095 rules per sheet, and 4 levels) applied to IE 6 through IE 9. The limits were increased in IE 10 to the following:

  • A sheet may contain up to 65534 rules
  • A document may use up to 4095 stylesheets
  • @import nesting is limited to 4095 levels (due to the 4095 stylesheet limit)
Night Owl
  • 3,968
  • 4
  • 25
  • 37
  • 1
    Again, the limit is not in the number of *rules*, but in the number of *selectors* . – connexo Nov 04 '15 at 17:16
  • The text "4095 rules" or "65534 rules" is directly from the text on an MS IEInternals 2011 blog post and can also be found in KB Q262161. It's likely a matter of semantics. In many definitions of "rule" or "rule set" the "selector" is the portion of the "rule" outside of the "declaration block" which can be a single selector or a selector group. Using that definition all rules technically have only one selector even if that selector is actually a group of specific individual selectors. -> continued -> – Night Owl Nov 05 '15 at 20:01
  • I confirmed that IE 10 has a higher limit (I suppose the new limit is 65534 as Night Owl said?) than IE 9 by using isNaN1247's gist (https://gist.github.com/2225701) with IE 9 and IE 10: https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/mac/ – David Winiecki Apr 23 '16 at 00:07
5

A nice solution to this problem for people using Grunt:

https://github.com/Ponginae/grunt-bless

Tom Teman
  • 1,802
  • 2
  • 27
  • 43
  • Of course, check out the [issues](https://github.com/Ponginae/grunt-bless/issues) before you use it. – Oliver Jan 27 '15 at 20:26
  • It's a grunt wrapper for [bless.js](https://github.com/paulyoung/bless.js/) btw, which seems pretty solid. – Tom Teman Jan 27 '15 at 21:57
4

Developer tools within FireFox dev edition shows CSS rules

Might be handy for those of you still fighting with older IE versions / large CSS files.

FF Developer Edition Website

Dev tools - FF

Mike Hague
  • 193
  • 2
  • 13
-1

I think it's also worth noting that any CSS file larger than 288kb will only be read up until that ~288kb. Anything after will be completely ignored in IE <= 9.

http://joshua.perina.com/africa/gambia/fajara/post/internet-explorer-css-file-size-limit

My advice is to keep CSS files for larger applications split up into modules & components and keep a constant eye on filesize.

Shannon Hochkins
  • 9,930
  • 11
  • 50
  • 88
  • From some extended research, it doesn't look like it's a file size limit, but rather a selector # limit. I could not find any official documentation verifying this fact. – Arya Apr 03 '18 at 18:02
  • See https://stackoverflow.com/questions/49683077/is-there-a-css-file-size-limit-in-ie9 – Arya Apr 12 '18 at 01:33