過去のCSSの奇妙な挙動
CSS Curiosities of the Past (vale.rocks)
要約
この記事では、CSSが仕様外でどのように使われてきたか、ブラウザ固有のハックや非標準的な構文、そしてそれらがどのようにウェブ開発の歴史に影響を与えてきたかを探ります。プロパティ解析の悪用、ドキュメントレベルでのブラウザ検出、Clearfixハック、カーソルプロパティの非標準値、CSS Expressions、そしてInternet Explorerのフィルター機能など、過去のウェブ開発者が直面した課題と、それらを乗り越えるために用いられた創造的(かつ時に奇妙)な手法について解説しています。
全文翻訳
CSSの過去の奇妙な挙動
ウェブの興亡は、私たちを今日の地点に導きました。ウェブがたどってきた道のりなしには、現在のウェブは存在し得ないでしょう。しかし、その道のりのいくつかの段階は、控えめに言っても興味深いものでした。
CSSはウェブ上の要素をスタイリングするためのものですが、その誕生以来、時にはいくつかの追加の役割を担うことになりました。それは奇妙な役割を引き受け、おそらく持つべきではなかった振る舞いを拾い上げてきました。それが人生というものです。
私が奇妙で文脈依存のHTMLについて詳述したように、これは主に仕様外のCSSを見ていくものです。ブラウザ固有のハック、技術にスコープされた構文、そして疑わしい状況、企業の複雑さ、秘術的な実装から生まれたエンジン固有のスニペットです。
プロパティ解析
width: 300px;
*width: 250px;
_width: 200px;
-width: 200px;
ほとんどのブラウザは、アスタリスクで始まるプロパティを無効として正しく扱います。しかし、Internet Explorer 7以前はそれを有効とみなしました。それはあまりにも有名だったので、アスタリスクの形から「スターハック」という名前が付けられました。同様に、プロパティの前にアンダースコアやハイフンを付けると、Internet Explorer 6 のみがそれを有効とみなしました。これに似たハックは多数存在し、その大部分はbrowserhacks.comに最もよく文書化されています。主な要点は、一部のブラウザがプロパティ、セレクタ、値を誤って解析し、ブラウザの振る舞いが非常に多様だった時代にそれを悪用できたということです。
条件付きコメントをCSSファイル(HTMLドキュメント内で可能だったもの)で使用して、特定のブラウザにのみCSSを適用することはできませんでした。1。したがって、何が無効で何が有効であるかという疑わしい解析のこの悪用は、特定のブラウザをターゲットにするために一般的でした。
Important
background: red !interesting;
Internet Explorer 7以前は、感嘆符で始まるほぼすべてのテキスト文字列を!importantとして扱いました。最も一般的には、人々は!ieと書いて、スタイルがInternet Explorerでのみ優先度を上書きできるように利用していました。Internet Explorerにとっては、任意の!bananaと仕様通りの!importantは同じでしたが、他のブラウザは後者のみを正しく受け入れました。
Internet Explorer 6以前には、同じブロック内で後で宣言されたスタイルが!important値を上書きするという関連バグもありました。例えば、ここでは色が白ではなく黒になります。
color: white !important;
color: black;
ドキュメントレベルのブラウザ検出
CSS経由でドキュメントレベルでどのブラウザが使用されているかを特定する方法は数多くありました。例をいくつか挙げます。
- Internet Explorer 6以前では、
* html {}と書くことができました。 - Internet Explorer 7のみでは、
*:first-child+html {}を使用できました。 - Internet Explorer 7以外のブラウザは、
html > /**/ body {}をサポートしていました。 - Firefoxの初期バージョンでは、
body:empty {}(bodyにコンテンツがあっても)内のスタイルが適用されました。
このアプローチは、特定のブラウザのみの要素をターゲットにするために複数の下降セレクタを書く必要があるため、使用するのが厄介なことがよくありました。
Clearfix
.clearfix {
zoom: 1;
}
バージョン8まで、Internet ExplorerにはhasLayoutという概念がありました。内部フラグであり、要素が自身をレンダリングする責任があるか(true)、それとも親要素が責任を持つか(false)を指定しました。当然ながら、これは難解で混乱を招くシステムでした。<img>、<iframe>、およびほとんどの入力関連の要素は、本質的に「レイアウトを持つ」ものでした。他の要素は、特定のCSS宣言によって明示的に与えられない限り、レイアウトを持ちませんでした。
レイアウトを持たない要素は、奇妙なマージンやボーダーの振る舞い、配置の複雑さ、一般的な奇妙なレンダリングに遭遇する可能性があり、最も重要なのは、子要素がフロートされたときに親コンテナが折りたたまれる原因となりました。これは、ページレイアウトの事実上の方法であったフロート要素の時代に、あらゆる種類の問題を引き起こしました。
zoomプロパティは、ターゲットが表示されるサイズを変更します。値が1の場合、ターゲットは既存のサイズで表示されます。これは無駄に見えるかもしれませんが、zoomは要素にレイアウトを与えるため、要素の外観を変更せずにレイアウトを与える簡単な方法として使用されました。
ハンドカーソル
cursor: pointer;
cursor: hand;
Internet Explorer 6以前では、Internet Explorerはcursorプロパティのpointer値を尊重しませんでした。代わりに、指差しハンドを提供する非標準のhand値のみをサポートしていました。そのため、サイトは両方の値をCSSに記述することが一般的でした。cursor: handはInternet Explorer以外のブラウザでは無効とみなされ、Internet Explorerがhandを使用する一方で、それ以外のブラウザはpointerを使用するという期待がありました。
CSS Expressions
top: expression(eval(document.documentElement.scrollTop));
正式には「Dynamic Properties」と呼ばれるCSS Expressionsは、CSSでJavaScriptを実行する方法でした。これは、position: fixed(上記のコードスニペットが対処しているもの)やmin-width、max-widthなどのスタイリング機能の遅れを補うために、Internet Explorer 5で導入された非標準の動作でした。これにより、レイアウトの作成が非常に困難になりました。CSS Expressionsはハック的で扱いにくく、多くの複雑さを露呈しました。Date()を使用して、時間帯に基づいて適用されるスタイルを変更することさえできました。CSS Expressionsは常に再評価されるため、パフォーマンスに非常に大きな負荷がかかりました。Steve SoudersがYahoo! Developer Network blogで指摘したように:
Expressionsの問題は、ほとんどの人が予想するよりも頻繁に評価されることです。ページがレンダリングおよびリサイズされたときだけでなく、ページがスクロールされたとき、さらにはユーザーがマウスをページ上に移動させたときにも評価されます。
Microsoftは、劇的なタイトルの投稿「Ending Expressions」で発表したように、Internet Explorer 8でそれらのサポートを終了しました。
Filters
Internet Explorerには多くの不安定な挙動があり、opacityのような基本的なプロパティでさえ、多くの視覚効果において他のブラウザに遅れをとっていました。そのため、Microsoftは独自のフィルター機能を導入しました。フィルターはWindowsのDirectXベースのコンポーネントを使用しており、ウェブプラットフォーム標準からはかけ離れていました。Internet Explorerはバージョン4で最初にフィルター機能を導入しました。構文は非常にシンプルで、要素の不透明度を下げる例は次のようになります。
filter: alpha(opacity=50);
完璧とは程遠いものでしたが、Explorerの多くの欠点に対処することを可能にしました。フィルターは要素にレイアウトが必要であり、また、小さなテキストのClearTypeフォントアンチエイリアシングを煩わしく剥がしてしまうため、ギザギザに見えました。時にはインタラクティビティの問題を引き起こすこともありました。バージョン5.5では、フィルター構文はより複雑になり、次のようになりました。
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50);
DXがDirectXを参照していることに注意してください。フィルターはアニメーション化することさえできました。フィルター機能の最後のアップデートで、MicrosoftはCSS標準への準拠を向上させるためにバージョン8でフィルタープロパティにベンダープレフィックスを付けました。また、フィルターがフォントのアンチエイリアシングを剥がさないようにし、値を引用符で囲む必要がありました。
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=50)";
-ms-filterは最終的にInternet Explorer 10で削除されました。この削除は、Internet Explorerのレガシーモードにも及びました。バージョン10のリリースまでには、フィルターのほとんどの一般的な用途はブラウザによってサポートされるようになっていました。例えば、バージョン9で追加されたopacityプロパティなどです。
不透明度以外に、Explorerのフィルター機能の非常に一般的な用途の2つは、透明なPNG画像とグラデーションの処理でした。Internet Explorer 6以前では、PNGの透明な部分はグレーの背景に置き換えられました。後続のバージョンでも、PNGは通常ガンマに関連する問題に遭遇する可能性がありました。そのため、人々はしばしばAlphaImageLoader経由で画像を読み込みました。
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png');
グラデーションは、背景画像(linear-gradient()はInternet Explorerバージョン10までサポートされませんでした)の代替としてfilterで適用されました。
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='red', endColorstr='green', GradientType=0);
人々は、前述のCSS Expressions機能を使用して、一般的に遭遇する状況に対して簡単な再利用可能なフィルターを実装することがよくありました。
スクロールバーのカスタマイズ
body {
scrollbar-face-color: #333333;
scrollbar-highlight-color: #666666;
scrollbar-3dlight-color: #000000;
scrollbar-darkshadow-color: #000000;
scrollbar-shadow-color: #111111;
scrollbar-arrow-color: red;
scrollbar-track-color: #222222;
}
Internet Explorerバージョン5.5は、スクロールバーの外観をカスタマイズする機能を紹介しました。
[画像: ダークカラーのスクロールバーと赤い矢印が表示されたInternet Explorer 11のウィンドウ。]
Internet Explorer 11で適用された上記のスクロールバーのスタイル。
矢印ボタンとサムについては、face-colorは背景を設定し、highlight-colorは内側の左ハイライトを設定し、3dlight-colorは外側の右ハイライトを設定し、darkshadow-colorは内側の右シャドウを設定し、shadow-colorは内側の右シャドウを設定し、arrow-colorは矢印アイコン自体を設定しました。track-colorは当然スクロールバーのトラックを設定しました。スタイルを生成するための完全なアプリケーションさえありました。
今日と同様に、スクロールバーのスタイリングはやや派手でやりすぎと見なされていたため、プロフェッショナルな文脈ではマイナーな調整に主に使用されていました。この機能はもちろん、MySpaceプロファイルをカスタマイズする人々によって最大限に活用されました。
HTML Components
.item {
behavior: url(csshover.htc);
}
HTML Components(現代のWeb Componentsと混同しないこと)は、Internet Explorer専用の機能で、バージョン5で追加され、バージョン5.5で大幅に拡張されました。これにより、CSS経由でスクリプトロジックをHTML要素にアタッチすることができました。多くの言語がサポートされていましたが、JavaScriptがほぼ常に使用されました。
以下は、リンク以外の要素でハック的なホバー動作を追加するために使用されるHTMLコンポーネントの例です。これは、Internet Explorerバージョン7以前で:hoverがサポートされていた唯一の場所でした。指定されている言語は「JScript」であることに注意してください。これはInternet ExplorerがサポートしていたMicrosoftのJavaScript実装です。
<PUBLIC:COMPONENT NAME="CSSHover">
<PUBLIC:ATTACH EVENT="onmouseover" ONEVENT="hoverOn()" />
<PUBLIC:ATTACH EVENT="onmouseout" ONEVENT="hoverOff()" />
<script language="JScript">
// マウスが入ったときにクラスを追加
function hoverOn() {
if (!/\bhovered\b/.test(element.className)) {
element.className += " hovered";
}
}
// マウスが出たときにクラスを削除
function hoverOff() {
element.className = element.className.replace(/\b\s?hovered\b/g, "");
}
</script>
</PUBLIC:COMPONENT>
この機能の特に一般的な使用法はProgressive Internet Explorerでした。これは、当時の最新のCSS機能をInternet Explorerバージョン6から9に移植しました。Internet Explorer 8以降、behaviorはベンダープレフィックス付きの-ms-behaviorとして利用可能になり、Internet Explorer 10でサポートが削除されました。
Box Model Hack
div {
width: 400px;
voice-family: "}"" ;
voice-family: inherit;
width: 300px;
}
Tantek Çelikによる非常に有名なハックです。voice-familyプロパティは、コンテンツを読み上げるときに使用されるボイスファミリーを指定するために使用されました。このプロパティは当時の古いブラウザではサポートされておらず、値は文字列として提供されていました。パーサーのバグにより、Internet Explorer 5は`