Internet Explorer CSS hacks with JavaScript

This post is more than 13 years old.

Sometimes it’s just easier to write a quick hack to get the job done. This is one of those times.

SWMBO, the CSS guru in the house, quite rightly wants to use the :before and :after pseudo-elements to add some style to a website, in a way that will make it easy for the client to add content without struggling with keeping the format consistent. That’s easy enough in Firefox, Safari, Chrome, Opera, even Internet Explorer 8 and 9… but not Internet Explorer 6 or 7.

There are some handy scripts floating around that help to fix this problem, especially the very handy IE7.js. But we’re already loading scripts to fix up some Internet Explorer deficiencies, and I don’t really want to play what-script-is-conflicting-with-what-other-script and why-is-performance-so-bad-on-IE. All I want is a simple fix for a couple of :befores and :afters.

The Hack

It turns out that IE (at least 6 and 7) will happily let you add CSS properties not defined in any standard, and then let you access them from JavaScript. For example, I have defined a new property for use in my script: “hack”.

Adding a “hack” property lets me tell my script that an element needs a hack applied to it. Additional properties can also be added, e.g. “content”, even though they are not supported by IE.

As an example, SWMBO wants to add an orange Q in front of any H3 element’s text. In a modern web browser, that looks like this:

body.page-id-75 section h3:before {
    content: "Q.\0020";
    color: #F68A33;
}

To convince IE6 and IE7 to do that, I add this to their individual stylesheets; note the unsupported properties “hack” and “content” and the lack of quotes around the value for “content”:

body.page-id-75 section h3 {
	hack: before;
	content: Q.;
}

body.page-id-75 section h3 .hack-before
{
	color: #F68A33;
	padding-right: 0.5em;
}

I then have some JavaScript that runs on page load, which scans through all the elements looking for my custom CSS “hack” property. When it finds one with a value of “before”, it inserts a span before the text node of the element. Of course, I only run this script fragment on IE6 and IE7!

var i, len, elements, element, currentStyle, hack;
elements = document.all;

i = elements.length;
while (--i >= 0) {
    element = elements[i];
    currentStyle = element.currentStyle;

    // check for special CSS attribute flagging :before
    if (currentStyle.hack == "before") {
        // insert a span element at start of this element
        hack = document.createElement("span");
        hack.className = "hack-before";
        hack.appendChild(document.createTextNode(currentStyle.content));
        element.insertBefore(hack, element.firstChild);
    }

    // ... other hack checks, e.g. "after"
}

Simple. Job is done. OK, it took me a little while to work that out, but I’ll use it again (and again) when SWMBO wants IE to play ball with CSS it doesn’t understand, and it’s a faster hack than IE7.js which has to parse all your style sheets to work out what to fix.