Browser incompatibilities are not quite my favorite bugs to find.
I recently got a bit more gray hair when I found out that Internet Explorer can’t handle more than 4,095 (2 ^ 12 – 1) selectors in a single CSS file. This is easy to run into when you’re using a framework like Rails’ asset pipeline or Compass where it’s so easy to make a single large CSS file.
In my application, the root cause of such large CSS files can be the combinatorial effect of selectors. For example, this SCSS will generate an explosion of rules:
.c1 .c2, .c1 .c3 { .c4 .c5, .c4 .c6 { .c7 .c8, .c7 .c9 { font-size: 100% } } } |
And the compiled CSS:
.c1 .c2 .c4 .c5 .c7 .c8, .c1 .c2 .c4 .c5 .c7 .c9, .c1 .c2 .c4 .c6 .c7 .c8, .c1 .c2 .c4 .c6 .c7 .c9, .c1 .c3 .c4 .c5 .c7 .c8, .c1 .c3 .c4 .c5 .c7 .c9, .c1 .c3 .c4 .c6 .c7 .c8, .c1 .c3 .c4 .c6 .c7 .c9 { font-size: 100%; } |
We’ve multiplied three straightforward lines into 8 rules. A few of these in your CSS can quite easily put you over the limit. I’ve found more than one solution, but nothing I’ve really felt confident in. I spiked a quick rack-pagespeed filter to try to automatically solve the problem, but a short investigation revealed that this avenue is not going to be a trivial effort.
In the end I did the simple thing: I just broke it up into two files. For a longer-term preventive measure, I added an acceptance spec (written with the steak framework) that will grab the compiled CSS files and alert me if any file exceeds the limit. The CSS parsing and counting is based on the CssSplitter code found here.
Here’s my spec:
It isn’t a perfect solution — I’d prefer if Sprockets just handled everything for me (it looks like people have worked on this, but I didn’t find anything polished). Even if it doesn’t fix the problem, it’s good to get a big red flag whenever it rears its ugly head.
Has anyone out there implemented a better solution?


3 Comments
nice solution – simple and to the point.
Here is a javascript snippet that tells you how many selector has each page
https://gist.github.com/4586719
Elie
Hi Elie,
That’s cool! It’s good to see such a short solution. It’s also nice to see it in JavaScript – it means we could update the capybara test to just run the JS in the browser, which I suspect would be more reliable than using a handful of regular expressions (which always feels brittle to me, even if it hasn’t broken yet).
Thanks for posting that!