9月11日、Vale.Rocksが「CSS Curiosities of the Past」と題した記事を公開した。CSSの黎明期から2000年代にかけて、Web開発者たちが編み出したブラウザ固有のハックや非標準仕様の数々を詳細にまとめたものだ。
CSSプロパティの値にJavaScriptを書く、DirectXをCSSから呼び出す、感嘆符の後に「banana」と書いても動く——こうした手法を「バグ」と片付けるのは簡単だ。だが実際には、それらは当時の開発者が生き延びるための現実的な選択肢だった。Interop 2026でブラウザ間の相互運用性が整備されつつある今だからこそ、あの時代の過酷さを振り返る意味がある。
CSSの中でJavaScriptを動かす「CSS Expressions」
この記事で最も読み応えがあるのが、CSS Expressions(動的プロパティ)の話だ。Internet Explorer 5が独自に導入したこの機能は、CSSプロパティの値としてJavaScriptを直接実行できるというものだった。
top: expression(eval(document.documentElement.scrollTop));
これは position: fixed を持たなかったIEの穴を埋めるために使われた代表例で、スクロール位置に追従する要素を実現している。IEが標準の min-width や max-width を未サポートだった時代、こうしたハックが真剣に使われていた。
問題はパフォーマンスだった。Webパフォーマンスの第一人者であるSteve Soudersは当時、「expressionはページのレンダリング・リサイズ時だけでなく、スクロール時や、ユーザーがマウスを動かすたびにも実行される」と警告していた。ページ上でマウスを動かすだけで式が再評価されるとなれば、パフォーマンスへの影響は深刻だ。MicrosoftはIE8でこの機能の廃止を「Ending Expressions」という大仰なタイトルの投稿で宣言した。
DirectXを呼び出すCSSフィルター
IEはOpacityすら標準対応が遅く、代わりにDirectXベースの独自フィルター機能を導入した。IE4から存在したこの機能は、バージョンを追うごとに構文が変化している。
IE5までのシンプルな構文:
filter: alpha(opacity=50);
IE5.5以降の複雑な構文(DXはDirectXの略):
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50);
IE8でのベンダープレフィックス版:
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=50)";
透過PNGの表示(IE6以前はPNGの透明部分がグレーに潰れた)やグラデーションも、このフィルターで対処していた。linear-gradient() がIEでサポートされたのはバージョン10になってからで、それまでは以下のような記述が現役だった:
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='red', endColorstr='green', GradientType=0);
「*」「_」で特定ブラウザだけに当たるCSS
width: 300px;
*width: 250px; /* IE7以下のみ有効 */
_width: 200px; /* IE6のみ有効 */
アスタリスクを使った「Star Hack」はIE7以下がこれを誤ってvalidと解釈したことを利用したものだ。アンダースコアはIE6のみが対象だった。HTMLの条件コメントのようにCSS単体でブラウザを分岐させる手段がなかった時代、パーサーのバグが積極的に活用された。こうしたハックの多くはbrowserhacks.comにアーカイブされている。
!important が !banana でも効いたIE7
background: red !interesting;
IE7以下では、感嘆符の後に続く文字列が何であれ !important と同等に扱われた。!ie と書いてIEだけに優先させる手法が広まったのはこのバグのためだ。他のブラウザは正しく !important のみを受け付けた。
IEのhasLayoutと zoom: 1
フロートレイアウトが主流だった時代を苦しめたのが、IE8未満に存在したhasLayoutという内部プロパティだ。IEはこのプロパティが有効な要素に対してのみ自身のレイアウトを「所有」させる仕様になっており、無効な状態では子要素がフロートした際に親要素の高さが失われるなど、数々のレンダリング不具合を引き起こした。
.clearfix {
zoom: 1;
}
zoom: 1 は見た目を変えずにhasLayoutを有効化する副作用を持つため、クリアフィックスの定番手法として広く使われた。
CSSからスクリプトを添付する「HTML Components」
.item {
behavior: url(csshover.htc);
}
IE5で追加されたHTML Components(現代のWeb Componentsとは無関係)は、CSSを通じてHTMLにスクリプトを紐付ける機能だった。IE7未満では :hover がリンク要素にしか適用されなかったため、この仕組みを使って他の要素にもホバー挙動を実装する手法が広まった。CSS3の機能をIE6〜9に移植したCSS3 PIE(Progressive Internet Explorer)もこの仕組みを活用していた。
記事ではこの他にも、IE5.5から存在したスクロールバーのカラーカスタマイズ、IEのBox Modelの解釈の誤りを逆手に取ったBox Model Hack、SkypeやAsk ToolbarがページのUI要素を勝手に上書きしていた問題へのCSSでの対処法なども取り上げられている。いずれも「仕様ではなくバグを使って実装する」という点で共通しており、当時のWeb開発の状況を今に伝える記録として読む価値がある。
詳細はCSS Curiosities of the Pastを参照していただきたい。