Yesterday I spent the entire day trying to narrow down a nasty CSS bug that only surfaced in Internet Explorer 8. Everyones favourite browser didn’t redraw a pseudo element created via :before when its style got changed by adding or removing a class via JavaScript. It was a custom checkbox element with a JavaScript click handler that simply toggled a class on every click.

Getting to the bottom of it

Here is a jsFiddle with a trimmed down version of said checkbox. Normally a click into the little black square should toggle its background color. But when you try to do it in IE 8, you’ll see that nothing happens. Now here is a working version. What’s the difference, you ask? It’s small and hard to spot: the value of the content property!

As it turns out, IE8 only redraws pseudo elements when their content changed. So the solution to fix the problem was to make sure to always use a different content value in every style rule. In my case I only had two and initially just used an empty string as value. So I simply added a space to the content of the checked style and the problem was solved!

.checkbox:before {
    content: '';
}.checkbox.checked:before {
    content: ' '; /* <- extra space just to change the content */
    background-color: #ccc;
}

Now that wasn’t so hard, was it? Unfortunately it was pretty hard to find this solution, because at first I suspected it to be a bug in my JavaScript code. I’m now going to describe the things that mislead me to look for solutions in all the wrong places, hoping to save anyone in a similar situation some precious time.

The bumpy road to a working solution

The checkbox is part of a pretty big AngularJS app and was bound to the scope via ngClass and ngClick. So at first I though I was doing something wrong. So I examined the code very closely and was pretty confident that nothing was wrong with it.

I noticed that, even though the checkbox didn’t get redrawn right on click, it did get redrawn when the mouse cursor got moved out of the containing element. It looked almost as if a mouseleave handler was bound to it, that triggered the refresh. But that was not the case. Nonetheless, I spent some time googling terms like angular, ng-class, mouseleave, ie8 & bug in various combinations with other terms that seemed relevant. Unfortunately with no results.

As I grew more and more desperate, I even started to debug the ngClass directive itself. I found out rather quickly, that the problem was not JavaScript-related, since the directive seemed to be working properly and the click caused the associated JavaScript code to execute nearly instantly.

So at least now I knew that I had to leave Angular and JavaScript in general out of the equation and started googling again. This time with focus in CSS and rendering issues. And finally I stumbled over a post on StackOverflow with my exact problem and a proper solution: Forcing IE8 to rerender/repaint :before/:after pseudo elements.

From there it was just a matter of seconds to fix the problem. I hope this blog post saves at least one other poor soul from wasting as much time on this annoying bug, as I did.