This Thanksgiving I've decided it's about time that I provided some more background and analysis on one of the things I am certainly unintentionally (in)famous for. This entry was started at 7pm on Thanksgiving evening, but took me until now to complete.
I don't know who first came up with using the presence of a '
media' attribute on
<style> to hide CSS from Netscape 4, but it was the first technique that I remember hearing of to use a perfectly reasonable HTML feature (yes, the 'media' attribute is in HTML, not CSS) to deliver CSS selectively to browsers that supported a certain feature.
This HTML-based "filter" was perhaps the first such technique, though it would be many years before the term "filter" was introduced as a general term for such techniques.
The first filter I came up with (again, before they were named as such) was perhaps the @import with quotes filter, which I didn't even bother writing a page about in particular because it seemed so simple: @import "foo.css"; is only supported by IE5, NS6, Opera3 and better. I just posted an example usage at the time for Web Standards Project's Browser Upgrade Campaign (BUC). That particular legacy contribution was also made anonymously to one of the ALA redesigns, though I believe Jeffrey has outed me at some point since.
Neither the HTML 'media' attrribute filter nor the CSS @import quotes filter, in my humble opinion, qualified as hacks, because they lacked what some might term the essence of a hack:
either a kludge, or the opposite of a kludge, as in a clever or elegant solution to a difficult problem. Neither of those filters were particularly kludgy (warning, not a Scrabble word), nor clever. In other words they were too "obvious" to really be considered hacks.
Anyway, the @import filter seemed harmless enough. At the time the only big difference it made was to filter out IE4.x (both Mac and Windows), which had already been obsoleted by IE5 (both versions). And it was praised as:
... for people who make websites, that is nothing short of revolutionary.
Sidenote: note the fact that that article on ditching <table>s for layout is almost FIVE years old
yet those of us that are real professionals still have to repeat the message .
Thus the idea of using a feature of CSS to essentially do a lightweight form of browser specific style sheet switching was born, but the Pandora's Box (Model) of CSS Hacks had yet to be opened. That would come exactly one week later.
Jeffrey Zeldman expressed to me how nice it was that it was possible to write CSS without having to worry about what might look bad in (or even crash) obsolete browsers like Netscape 4. Having been freed to use more of (and depend more on) CSS, he and many others following A List Apart's suggestions quickly ran into the next issue which was the inconsistent box model treatment between IE5.x/Windows and IE6/Windows.
If only there were a way to send one width to IE5.x/Windows, and another width to modern browsers which supported the CSS box model... is a rough approximation of what Jeffrey said (emailed) to me at the time.
Eager to be helpful, and armed with the intuitive knowledge that the key to Pandora's Box of CSS hacks could be hidden amongst the jungle of CSS1 section 7.1 parsing tests, I went hunting. It didn't take long until (with Todd Fahrner's help) I discovered how test twentyb (
rotation-code: "\"}\""; — look familiar?) messed up all versions of IE5.x/Windows,
but no other modern browser. After that it was a simple manner of finding an abandoned CSS2 property which accepted arbitrary string values.
I had opened Pandora's Box (Model) of CSS Hacks, and there was no turning back.
Implicit in the story above are a set of design principles which I kept in mind when I first set about creating CSS hacks, and which I really should have noted at the time. Given all the hand-wringing about CSS hacks incited by my colleague Markus Mielke, it's about time I documented these principles. More on the hang-wringing later.
But I didn't document those principles at the time. Once said Pandora's Box was opened, it didn't take long for the notion that hacking CSS was a "good idea" to spread far and wide in the web design and development community (much further than I could have possibly expected, to the #4 result for 'hack' on Google, and even onto t-shirts!). Of course once hacks for IE5.x/Windows had been discovered, and refined into the concept of "filtering" which browsers got to see whole style sheets, it was only a matter of time before hacks were developed and documented for nearly every browser. Nevermind that so many of the hacks violated the above-mentioned principles. Those ideas spread and mutated without any such strings attached.
At this point I can only strongly recommend that people evaluate these myriad hacks based on the above principles before using them.
The irony is that I don't disagree with the details of Marcus's MSDN post. Note that his "Call to action: Please check your pages" does not mention a single one of the CSS hacks I developed. The one partial overlap is the use of the child ">" selector, which was introduced as part of the Box Model Hack to "Be Nice To Opera" (Opera 5 in particular, which at this point is probably ignorable — anyone even hear of anyone that still uses Opera 5, even for testing purposes?).
The sad thing is that most of the hand-wringing could have been avoided (as noted in the comments) if people would first try fully standards based cross-browser solutions before resorting to hacks.
However, the undertone of that blog post (and what Markus and Chris Wilson have expressed to me and others in person) is that web developers must stop using CSS hacks altogether.
I know that's perhaps a bit of a hyperbole, but that's the message that's been heard nonetheless. However, such a message is, with all due respect, the impractical perspective of folks who are not a professional web designers / developers. I know this, I was there once too.
To be specific, the problems with hacks have arisen because of hacks that are targeted at a current browser, namely, IE6/Windows. E.g.
And a misperception that the use of an implemented feature is a hack.
E.g. people (ahem, starting with the "BMH" as noted) have used the child selector to send "valid CSS" to "compliant implementations", e.g. with
That's not a hack. It's not targeting a specific browser. It's actually inclusive of all browsers who would support CSS2(.1) selectors.
Sending valid CSS to compliant implementations is proper behavior.
(With apologies to Star Trek)
Does this make it harder for new/late implementations (like IE7) to come along and support that selector?
Why yes it does. This is no surprise.
If you support the child selector, now all of a sudden you have to compliantly support all the other properties/values of CSS2(.1) that authors have been successfully using with the child selector.
But given that several other browsers do so (otherwise authors wouldn't be using the child selector), and thus the market has demonstrated this is not a problem, this is a reasonable expectation.
However, if a browser is somehow unable to do so, then the answer is simple.
Don't implement that selector, until that browser is able to do so. IE5/Mac did so, so can IE7, more than five years later...
This may seem "unfair" that that these features (a CSS2(.1) selector and some CSS2(.1) properties/values) are now "tied" together in terms of requiring implementation support, but guess what?
CSS2(.1) doesn't say you can implement part of the spec. You're supposed to implement the whole spec in the first place.
Obviously this was hard (in fact, impossible for self-contradicting and ambiguously written REC-CSS2 in 1998), and browser vendors (yours truly included) tried to do the next best thing, which is to implement logical "chunks" of CSS2(.1).
You need to keep coding just to keep up.
The bottom line: eventually what will happen (within a couple of years at most?) is that so many browsers will have implemented all of CSS2.1, and authors will be writing with that in mind, that any new browser that wants to support part of CSS2.1 will have to support all of it in order to support the style sheets in the wild.
IMHO, that's called progress.
But we don't have any fully compliant CSS 2.1 browsers yet. And we still have obsolete/abandoned browsers with enough marketshare (or machine dependence) to warrant the incremental bit of effort to support them. So for now:
<legend>in IE6/Windows), and specify that styling explicitly instead of depending on the defaults.
If you've made it this far, you've been extraordinarily patient and have the attention span of a savant. I wish you a happy Thanksgiving holiday.
I related some recent no fun experiences to my friend and co-worker Derek, in particular experiences relating to trying to be helpful, and then being taking advantage of, or having stuff neglected, or just being treated like I didn't matter, which was very odd, since I was the one providing help! I don't want to get into the details because frankly I don't wish to dwell on them.
My loss in this recent case was more emotional than financial (though I probably have about a couple of hundred dollars worth of stained pillows and blankets which might be treatable, as if I have the time to deal with that).
But regardless, John's philosophy still makes a lot of sense, and is something that I am learning to accept and embrace because it makes a lot of sense to me.
If you're nice to people, and help them out, sometimes you're going to get taken advantage of and lose some time, or some stuff. Hopefully you won't lose a friend, but sometimes that can happen as well.
I'll also consider the loss of time and stuff to be part of my optimism tax. I'll accept that from time to time I will have to pay this fee in exchange for optimistic freedom.
I prefer to pay this tax, and remain optimistic about people, and the world, rather than be focused on the negatives.
As John says:
the cost to my quality of life (by worrying more) is far more expensive than the cost of losing some stuff.