TL;DR: IE has a number of limits in the way it loads CSS, which can cause your styles to not be applied if you exceed them.
Internet Explorer has a number of limits in the way it loads CSS, which can cause some of your styles not to be applied if you unknowingly exceed them.
IE9 and lower
- A stylesheet may contain up to 4095 selectors
- A document may load up to 31 stylesheets
- A stylesheet may @import up to 31 other stylesheets
- @import nesting is limited to 4 levels deep
- This is goofy, but you can load 31 stylesheets that each import 31 others, for a total of 961. And each of those imported stylesheets could import 31 more, and so on, up to a depth of 4, for a total of 314 (or 923,521), but I don't have a test case for that.
All versions of IE
- A stylesheet may contain up to 65,534 selectors
- A document may load up to 4095 stylesheets
- @import nesting is limited to 4095 levels (due to the 4095 stylesheet limit)
- The IE10 Dev Guide says the limits for IE10 have been removed entirely, but in the comments of his blog post on the IE limits, Eric Law says these limits for IE10 are accurate. Again, I don't have a test case for this.
It can be easy to hit the 4095 selector limit if you're aggregating all your CSS into one file, especially if you include a framework like Foundation. Similarly, for years now, Drupal has included a feature to aggregate CSS files specifically to avoid the 31 imported stylesheet limit.
I put this post together because I couldn't find a single definitive reference or collection of test cases, and I was seeing some FUD on Stack Overflow threads.
Eric Law (former IE program manager) explains the source of the limits:
Internally, all software must decide how much storage space to allocate for a given variable, and all storage space is inherently limited by the memory and disk available.
In the case of IE, the data storage chosen was a 32bit integer [to identify, sort, and apply the cascading rules], which provides high-performance. ...The integer’s 32bits are split into five fields: four sheetIDs of 5 bits each, and one 12bit ruleID. The 5 bit sheetIDs results in the 31 @import limit, and the 12 bit ruleID results in the 4095 rules-per-sheet limitation.
While these limits are entirely sufficient for most sites, there are some sites (particularly when using frameworks and controls) that can encounter the limits, requiring workarounds.
In IE10, the allocation of the bits in that 32bit integer was adjusted to better meet the needs of real-world pages, and in practice, we'd never seen a page which did not work with the new allocation pattern.
My guess is that other browsers are either using a 64bit integer, which has an increased memory and CPU cost, or they had a smarter allocation of bits within a 32bit store—like IE10's—to start with.
- Bless will split your stylesheets to avoid the 4095 selector limit.
- Parker is a stylesheet analysis tool. It runs metrics on your stylesheets and will report on their complexity.
- 4095 selector limit
- 31 stylesheet limit
- 31 @import limit
- 4 nested @import limit
- font-family length limit
- Stack Overflow: Internet Explorer's CSS rules limits
- Stack Overflow: How are media queries counted in IE's CSS selectors limit?
- John Albin: 31 Reasons to Hate Internet Explorer
- IE Internals Blog: Stylesheet Limits in Internet Explorer
- Microsoft Knowledge Base: A webpage that uses CSS styles does not render correctly in Internet Explorer
- IE10 Dev Guide: Removal of style sheet limits
- Reddit: Did you know IE9 has a 31 character limit for font-family names in CSS?