CSSハック

CSSハックについて

ウェブ製作において、ブラウザ間の表示の差異はどうしてもつきまとう問題の一つ。そんな時に利用するのがCSSハックです。CSSハックは、ブラウザのバージョンごとの解釈の違いを突いて、目的のブラウザのバージョンごとに指定を行うなど、細かい調整の切り分けに使うものです。ただ、文法的に間違った書き方をするものがほとんどなので、ブラウザのバージョンアップによっては将来的に予想外の不具合を起こす可能性があります。

なぜ、ブラウザ間で表示が異なるのか?

そもそもの話ですが、ウェブサイトの表示がブラウザごとに異なるのは、ブラウザがHTMLやCSSやjavascriptの言語の解釈が異なるからです。これらの言語の解釈を行うのが「レンダリングエンジン」というプログラムなのですが、ブラウザによって搭載しているレンダリングエンジンが違うんです。だから表示が異なる→製作側が頭を悩ませる→ハックが活用される、というわけです。

主要ブラウザ用CSSハックまとめ

各バージョンごとに様々なCSSハックを編み出されましたが、2013年10月現在での情報をまとめてみます。ブラウザのバージョンアップに伴い、今では使えないハックもたくさんありますよ。

IE6以下

アンダースコアハック

プロパティの前に「_(アンダースコア)」を記述。W3C CSS Validatorではエラーが出ますが、記述が短いのがメリットです。

.text { _color: #f00; }

スターハック

セレクタの前に「* html」を記述。こちらはW3C CSS Validatorのエラーはありません。
※一応、macIE5も対象です

* html .text { color: #f00; }

インポータントハック

IE7やモダンブラウザは、後に記述されたものよりも「!important」を優先しますが、IE6は後を優先するので、そこを突いたハックです。文法的にも問題ありません。使い方は簡単で、一般的に使いたい指定を先にImportant付きで記述し、IE6以下で指定するものは後に記述するだけ。

.text {
 /* 通常の指定 */
 color: #f00 !important;

 /* for IE6 */
 color: #00f;
}

IE6以外

チャイルドセレクタハック

セレクタの前に「html > body」を記述。子セレクタに非対応なIE6の特徴を突いたハックです。W3C CSS Validatorのエラーもありません。

html > body .text { color: #f00; }

IE7のみ

スター+ハック

セレクタの前に「*+html」を記述。W3C CSS Validatorのエラーもなく正しい文法なのですが、Mac OSXのIEや古いOperaでも認識されてしまうので、この次に紹介する「IE7スターハック」が主流です。

*+html .text { color: #f00; }

IE7 スターハック

セレクタの前に「*:first-child+html」を記述。W3C CSS Validatorではエラーですが、他のブラウザバージョンに影響を与えることがないのがメリットです。

*:first-child+html .text { color: #f00; }

IE7以下

アスタリスクハック

プロパティの前に「*(アスタリスク)」を記述。W3C CSS Validatorではエラーですが、記述が短いのがメリットです。

.text { *color: #f00; }

IE8

\9ハック

値の末尾に「\9」を記述するだけ。IE8がリリースしてすぐに登場したハックで、当時は確かにIE8でしか適用されないものでした。が、その後のIE9やIE10などでも対応してるんですね。つまり今では”IE6/7以外”とか”IE8以上”のハックという解釈が正解です。

.text { color: #f00\9; }

で、もう一つ。セレクタの前に「html>/**/body」を記述するもの。こちらも上記と同様にIE9以降も対応しちゃうので使えません。

html>/**/body .text { color: #f00\9; }

IE9

ノットターゲットハック

セレクタの後に「:not(:target)」を記述。IE9がリリースした頃に登場したハックですが、現在ではIE9やIE10はもちろん他の主要ブラウザでも対応してます。なので、今ではこのハックで適用されないのは”IE8以下”となります。

.text:not(:target) { color: #f00; }

IE9と10

アットメディアゼロハック

スタイルを「@media screen and (min-width:0\0){}」の中に記述。ですが、IE11でも適用される可能性があります。私の環境ではIE11をまだ導入していないので確認できてません。

@media screen and (min-width:0\0) {
 .text { color: #f00; }
}

IE10

アットメディア エムエスハイコントラストハック

スタイルを「@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none){}」の中に記述。ですが、こちらもIE11でも適用される可能性があります。私の環境ではIE11をまだ導入していないので確認できてません。

@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
 .text { color: #f00; }
}

Firefox

モズエニーリンクハック

セレクタの後に「, x:-moz-any-link, x:only-child」を記述するだけ。ただ、このハックはIE7にも適用されてしまうので使えません。

.text, x:-moz-any-link, x:only-child { color: red; }

ちなみにもう一つ、セレクタの後に「, x:-moz-any-link, x:default」を記述するものがあります。上のと同系統で、「x:only-child→x:default」に変わっただけです(FF3以上対象)。こちらもIE7にも適用されてしまうので使えません。

.text, x:-moz-any-link, x:default { color: red; }

モズドキュメントハック

スタイルを「@-moz-document url-prefix() {}」の中に記述。この記述だとFirefoxのみに適用できます。ただW3C CSS Validatorではエラーが出ますが…。

@-moz-document url-prefix() {
 .text { color: #f00; }
}

Chrome

ウェブキットハック

スタイルを「@media screen and (-webkit-min-device-pixel-ratio:0) {}」の中に記述。webkit系ブラウザに適用させるハックで、ChromeとSafari3に適用されます。ちなみにChormeはwebkitからBlinkへとエンジンが変わりバージョン28から採用されています。現時点ではこのハックは有効ですが、今後はどうなるか分かりませんので過去にウェブキットハックを使っている場合はご注意を。

@media screen and (-webkit-min-device-pixel-ratio:0) {
 .text { color: #f00; }
}

Safari

xmlns属性セレクタハック

セレクタの前に「html[xmlns*=””]:root」を記述。Safari2~3.1が適用になるようです。※検証してません

html[xmlns*=""]:root .text { color: #f00; }

Opera

Operaハック

セレクタの前に「html:66irst-child」を記述。Opera9.25以降が適用となるようですが、Opera15では反応しませんでした。

html:66irst-child .text { color: #f00; }

さいごに

CSSハックは使い勝手が難しい

上記に挙げたハックを見てもらうとわかりますが、「当時はそのバージョン限定」だったのにその後のバージョンでも使えてしまうものとか、「特定ブラウザのみ対応」だったのに他のブラウザでも使えてしまうものなど、予期せぬ状況が生まれています。

その理由は、冒頭にも書いたようにCSSハックとは「各ブラウザバージョンのバグや非対応の側面を突いた手法」だからです。バージョンアップするたびにバグが改善されるのは当たり前です。逆に、当時は特定のブラウザでしか解釈できなかったから使えた文法的に正しいハックは、バージョンアップに伴い多くのブラウザが正常に読み込めるようになります。

安心して今でも使えるハックといえば、IE6/7/8あたりのものでしょうか。あとは正式に使える方法としてベンダープレフィックスもありますね。これについては改めて記事にしていこうと思います。それと、今回のハックをデモページにまとめておきました。