Internet Explorer and its (2^12-1) bug

21st July 2015

Incompatibility of browsers is not one of my favourite bugs to find, and recently I got a bit more grey hair working with Internet Explorer, IE9 specifically.

You may have come across this situation when your site styles stop rendering correctly in IE browsers and you used all sorts of hacks and scripts that you could think of, and the problem still occurs, and you ask yourself why is this only happening now?

Well, did you ever think that this could be because you have too many CSS selectors? Yes, that’s right, too many CSS selectors!

Internet Explorer 6 through 9 have a CSS selectors bug which limits the browser to only load the first 4,095 selectors from the stylesheet. You may now be questioning how could someone possibly be using those many selectos in one stylesheet, believe it or not this is possible and in many instances easily done using languages such as SASS to compile a single minified CSS file.

After coming across this issue when working in one of our projects, I invested a few hours to find tools and techniques to avoid getting in such trouble again. 

What tools could I use?

Before you actually start thinking of using any tools or software, it is first important to know whether you are going to run into that situation or not. Below are some of the techniques that can be used to discover whether you are experiencing such bug:

1. JavaScript Console Injection

As a starting point, when your site has finished loading, the provided JavaScript code can be pasted into the console of the browser, so it can count the number of selectors that live in the loaded stylesheets. Also, this will notify you of whether the CSS file is fully supported by IE browsers, and if not it will make you aware of the number of selectors that you are over the limit, which would be ignored by IE6-9 browsers. Download JS Injection Code

The downside of this is that you will have to run this often to find out how many selectors you have all together at that stage.

2. Grunt Task

There are better ways to debug this and another technique is to use grunt task runner, grunt-css-count, which will report the number of selectors being used in the stylesheet, as well as how many levels deep your selectors go, the number of rules being used and more.

It is great if you are already using grunt to build your minified CSS, or alternatively you will have to find a different method to achieve this with your task runner. If you are interested in grunt and wanted to include this in your projects, please use the getting started guide.

Once the issue is identified we can then use tools to bypass this, and one of the tools that I found extremely useful was Bless.

Bless splits your CSS file into the minimum amount needed in order to bypass the selector limit issue, so if your stylesheet had more than 4095 selectors it will split this into two or more css files and it will use @import to include the newly generated files into the main CSS file. The benefit of this is that it splits the CSS file automatically, so there is no need to manually count and find an appropriate place to split the CSS. Another factor that is useful about this is the use of @imports, which means we only need to include the path of the main CSS file in the HTML Head tag, so all you will have to do once your CSS file is Blessed is deploy all of the CSS files in one go.

How do I get started with Bless?

Bless can be ran in two forms:

1. Bless as an application

Installing it in your machine and running it when you want to. This means you have to install the application and feed the system manually every time you make a CSS change. Instructions on how to make use of this approach can be found here.

2. Bless grunt task

This is the approach I would recommend, as it runs the grunt task to split the css file automatically when compiled, only if excessive number of selectors are found. In order to get started with the setup of grunt-guess task runner, please refer to the relevant npm package.

What can be done to avoid this IE issue?

Having found the solution for the problem, this doesn’t mean we can lie back and relax. More time should be spent in improving the quality of the CSS selectors, and perhaps improving the team's front-end best practices. 

Some of the things that can be taken into account at the early stages of projects include:

  • Don’t be too specific with your selectors when applying styles, as the same styles may be needed somewhere else in the page. If you are very specific it would mean another selection of selectors would have to be created and assign the sames styles to it. Also always bear in mind on how deep you go, ideally you should only go 3 to 4 levels down, however if it is necessary to be very specific then there is nothing stopping you from doing so.
  • When using SASS, be aware that @extend can be very dangerous and cause duplication of code, and if the selector to be extended contains any children then all of them will be created inside the selector, resulting in duplications.
  • When using SASS, make use of @imports appropriately, and mixings can come in handy  many occasions and they can sometimes even replace @extend.
  • There is also the possibility of organizing your CSS files in features and modules, and building multiple CSS files for those features and modules and then import them all into the main CSS file. This approach will minimize the need of using Bless later, as your CSS files would already be split nicely.

Main points to take away

All in all, sit down with your team members and perform good testing in IE browsers and see if there is any need to take actions due to the 4059 selector bug. Once the issue has been identified, use the tools outlined in this blog post to fix the styling of the pages and review the CSS selectors and possibly escalate the issue to your front-end team leads in order to review the best practices and look for opportunities where improvements can be made.

This article was written by Jenish Chandracim who is a Developer at MMT Digital.

The original article can be found at http://www.mmtdigital.co.uk/blog/july-2015/ie9-bugs