The Triple-X hack - an exclusive CSS filter for IE7

Published: 8th February 2006

Legacy warning: this is an old article, and no longer a practical solution for hacking IE7. It turned out that any selector starting with "*+html " will apply exclusively to this browser.

If you've had a look at a few different sites in IE7 beta 2, then your estimation of this new browser may be similar to my own - it's actually pretty good. Most of the serious CSS bugs from IE6 are now fixed, while it's support for the range of CSS2 selectors (and even some CSS3) is a real boon.

Dropping support for the * html hack was clearly the right thing to do - that hack targets problems in IE5 and IE6, which for the most part no longer exist in IE7. So it amounts to a nice, clean division for adjustments that only the older builds require.

Nevertheless, IE7 does still have CSS bugs - two new bugs [New 1, New 2], and one that still exists from earlier builds [Old 1], as far as I know. The two new bugs may well be fixed before the next beta or final release; the older one, I suspect, probably not.

But either way, new bugs will inevitably be discovered, as they are in all browsers over time. And as good as it is, it still falls plenty short of the bleeding-edge CSS implementations of recent Opera and Mozilla builds. Ultimately we will need a targeted CSS filter for IE7 - a hack which applies or excludes CSS specifically from that browser.

And so ...

And so I'm pleased to say I've found one (with a little help from David "liorean" Andersson).

It takes advantage of an unusual combination of implementations - IE7 and Opera 9 support CSS3 substring-matching attribute selectors, but they don't support the negation pseudo-class; other current browsers which support one or the other, support them both. We can further distinguish Opera 9 from IE7 by the former's support for CSS3 media queries.

The CSS looks like this:

p.test { color:red; }

p[id$="test"] { color:green; }

p[id$="test"]:not([class="xxx"]) { color:red; }

@media all and (min-width:0px) { p[id$="test"] { color:red; } }

which applies to this sample HTML:

<p class="test" id="test">
    This text will be green if the rule has been applied.
</p>

The first rule applies to all modern browsers. The second rule applies to any which support substring-matching attribute selectors, which is Mozilla, Safari, Konqueror, Opera 9 and IE7. The third rule applies to browsers which support both the attribute selector and the negation pseudo-class, which is Mozilla, Safari and Konqueror. This leaves IE7 and Opera 9, so the fourth rule uses a CSS3 media query to negate the style for Opera 9.

Crucially here, since the class name of the element does not contain the substring "xxx", the third rule is duly applied in those browsers. But since IE7 and Opera 9 support the attribute selector but not the negation, they don't apply the rule.

So, the filter can be used in this combination, to apply and then negate particular styles for IE7. Or the last two rules can be used on their own or with other hacks, to hide from IE7 styles that are only intended for Mozilla, Safari, Konqueror, or Opera 9.

An alternative is to do this:

p.test { color:red; }

p[id$="test"] { color:green; }

html[xmlns] p[id$="test"] { color:red; }

In this case, the third rule is applied by every browser which supports the attribute selector, apart from IE7. It would equally work with html[lang] or another attribute of the html tag, but in both cases it relies on knowing what kind of document it will be used on, so in production use I would favor the original hack, verbose as it is.

Get the files

Categories...

Ideas and prototypes

Some nebulous thoughts and unfinished projects:

Browsers and devices

Web development tips and information for specific devices:

Our internal search engine is currently offline, undergoing some configuration changes in preparation for a major site overhaul. In the meantime, you can still search this site using Google Custom Search.


In this area

Main areas


[brothercake] a round peg in a square hole, that still fits