Internet Explorer's CSS rules limits
Asked Answered
H

7

149

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.

Hammered answered 28/3, 2012 at 11:43 Comment(6)
It looks like the 4095 limit is per document according to habdas.org/2010/05/30/msie-4095-selector-limit and there is also a link to a test page you could try yourselfSonometer
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...Bayle
@Kolink some (bad) content management systems use templates which can lead to many CSS files being included. Unfortunately, I've seen the 31 <style> limit reached on a number of occasionsSonometer
@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'. :PHammered
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.Bayle
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.Hammered
D
221

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.
Dow answered 28/3, 2012 at 11:50 Comment(9)
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.Hammered
After following a few links provided in the comments, I came across 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.Hammered
@Hammered - 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 - gist.github.com/2225701Dow
Thanks very much - that has confirmed that it is per-sheet, not per-page.Hammered
It should be noted that the 4095 limit applies to selectors, not rules.Chesterton
just for clarification: would the following line count as one "selector", or two? div.oneclass, div.anotherstyle {color: green};Weider
@anthony, two selectors, one rule.Dollar
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 - the limit is number of selectors, not number of rules or rulesets.Dolley
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 lolRolandorolandson
T
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();
Tyree answered 10/12, 2013 at 13:37 Comment(8)
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!Metaxylem
It is worth noting that you should not run this script in IE, since it will never emit the warning.Oust
Thank you for the script. It helped me debug a different errorWoven
This script is inaccurate. You should include a branch for @media rules, see https://mcmap.net/q/160475/-how-are-media-queries-counted-in-ie-39-s-css-selectors-limit.Bracteate
great script. keep in mind that if the stylesheets are from a different domain than the webpage, you will get null value for sheet.cssRulesVitiligo
I use this script everytime I have this problem - thank youDulcedulcea
The cross domain issue makes this less useful for me on a production website.Faye
Great code! In my case, as @Vitiligo 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.Lamdin
P
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

Perfectionist answered 23/2, 2015 at 17:18 Comment(2)
This is great. Thank you for editing the script to include media queries. Very, incredibly, super, highly helpful!!Fujio
This script is better than the one above.Poi
F
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)
Furtek answered 12/12, 2013 at 0:36 Comment(4)
Again, the limit is not in the number of rules, but in the number of selectors .Airport
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 ->Furtek
<- continued <- The blog author speculates in the comments that internally the selector groups are cloned such that each individual selector in a selector group becomes it's own rule and is counted individually. Thus "65534 selectors" has more relevant real world meaning but "65534 rules" is still technically correct.Furtek
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 (gist.github.com/2225701) with IE 9 and IE 10: developer.microsoft.com/en-us/microsoft-edge/tools/vms/macImpulse
A
5

A nice solution to this problem for people using Grunt:

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

Arabesque answered 12/1, 2015 at 8:38 Comment(2)
Of course, check out the issues before you use it.Intercessor
It's a grunt wrapper for bless.js btw, which seems pretty solid.Arabesque
R
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

Relation answered 13/11, 2015 at 10:22 Comment(0)
T
-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.

Testicle answered 4/9, 2015 at 7:2 Comment(2)
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.Wake
See #49683577Wake

© 2022 - 2024 — McMap. All rights reserved.