2009/06/11

clearfixの決定版を作る -IE編-

スタイルシートをめぐる冒険: clearfixの決定版を作る -IE編-
clearfixの決定版を作る -IE編-

今回は、floatバグ対策における鬼門ともいえるIEのclearfixに挑戦する。しかし、その前に、何をもって「決定版」とするか、あらためておさえておこう。本来なら、ひとつでも多くの種類、バージョンのブラウザでfloatをクリアできる(もしくは同じ効果を得られる)ことをもって、決定版とすべきなのだろうが、ここでは少し違う方針をとりたいと思う。簡単にいえば、CSS自体の正しさとか美しさを優先したいということだ。逆に、そのためには古いバージョンのブラウザなどは犠牲になってもしょうがない、と考えている。ここでいう「決定版」を定義してみよう。

1. 文法的に正しいこと
このこととイコールとするには異論があるかもしれないが、「W3Cのvalidatorを通ること」と言い換えることもできる。少なくとも、通らないより通るほうがいい。

2. 内容的に理にかなっていること、意味不明でないこと
いわゆるCSSハックは、記述通りに理解しようとするとその多くが意味不明である。文法的に間違っていれば当然として、仮に文法的に正しかったとしても、そういったテクニックにはなるべく頼らないようにしたい。また、CSSプロパティを本来とは異なる目的で使用することもできる限り避けたい。

3. シンプルであること
極力無駄な記述を省き、1行でも短くする。

さて、前置きが長くなってしまったが、本論に入ることにする。今回のIE編の検証にあたって用意したスタイルシートとHTMLは以下の通りである。(サンプルページはこちら)
【スタイルシート】 /* その1 */ .clearfixforie1 { height: 1%; } /* その2 */ .clearfixforie2 { display: inline-block; } .clearfixforie2 { display: block; } /* その3 */ .clearfixforie3 { zoom: 1; } /* その4 */ .clearfixforie4 { overflow: auto; width: 100%; } /* その5 */ .clearfixforie5 { overflow: hidden; width: 100%; } /* モダンブラウザ向けclearfix */ .clearfix:after { content: url(pixel.gif); display: block; clear: both; height: 0; } /* ボックスの設定 */ .wrapper { width: 200px; } .box-A { background: #cccccc; margin-bottom: 10px; } .box-B { width: 100px; height: 100px; background: #000000; float: left; } .box-C { width: 100px; height: 50px; background: #666666; float: right; } 【HTML】























簡単に解説を。

その1の「height: 1%」は、IE向け記述の標準形。通常は、IE以外に適用させないために、いわゆるスターハックと組み合わせて、「* html .clearfix { height: 1%; }」という形で用いられる。別名、Holly Hackとも呼ばれる。(IE Escaping Floats Bug 参照)

その2の「display: inline-block」は、一般にIE7およびMac版IE向けの記述とされるもの。すぐその後に、「display: block」としているのは、Opera、Safari対策である(inline-blockについては、inline-blockの奇妙な世界 参照)。

その3の「zoom: 1」は、IE5.5以降の独自拡張であるzoomプロパティを利用した記述で、Holly Hackと同じ効果をCSSハックに頼ることなく得られる。

その4とその5は、IEに限らず全ブラウザが対象で、いわゆるclearfixのようなややこしいことをしなくてももっと簡単にfloatをクリアできる、としてよく紹介されているテクニックである。(CSS - Clearing floats 参照)

さらに、モダンブラウザへの影響を調べるために、全ブラウザ向けのその4とその5を除いては、after擬似要素を用いたモダンブラウザ向けclearfixも併記した。

このソースを用いて、各ブラウザで検証してみた結果は以下の通りである。
IEの場合 7.0 6.0 5.5 5.0
その1(height: 1%) ○ ○ ○ ○
その2(display: inline-block) ○ ○ ○ ×
その3(zoom: 1) ○ ○ ○ ×
その4(overflow: auto) ○ ○ ○ ×
その5(overflow: hidden) ○ ○ ○ ○
モダンブラウザの場合 Firefox2.0 Opera9.21 Netscape7.1 Safari1.0
その1(height: 1%) ○ ○ ○ ○
その2(display: inline-block) ○ ○ ○ ○
その3(zoom: 1) ○ ○ ○ ○
その4(overflow: auto) ○ ○ ○ ○
その5(overflow: hidden) ○ ○ × ○

この検証結果を踏まえて、消去法でclearfixの決定版を探っていこう。

まず、最初に候補から外れるのは、その4とその5のoverflowを用いた方法だ。値がautoではIE5.0がダメ(この表にはないがMac版IE5.xも)。hiddenでは、Netscape7.1がダメ。さらに、Netscape6ではauto、hiddenともにレイアウトくずれが発生する。また、IE6以前用にwidth: 100%としなければならないのも、同時にpaddingやborderが指定できない点で汎用的なクラスとしての使い勝手を狭めている。

と、ここまでは簡単なのだが、次のステップで早々につまづいてしまう。残りの3つとも、それぞれ一長一短があり、頭ひとつ抜けたものがないのだ。ブラウザへの対応状況を優先するなら文句なしに「height: 1%」だが、その意味不明の記述がどうしても引っかかる。しかし、ここで冒頭に掲げた決定版の定義をあらためて思い出して、強引に話を進めることにしよう。

まず、IE独自拡張のためvalidaterを通らない「zoom: 1」は外す。次に、IE5.0は無視することにして、「height: 1%」も外す。これで自動的に、IE向けclearfixの決定版は「display: inline-block」ということになった。しかも、inline-blockという値自体には、Operaでも、Safariでも、Mac版IEでもfloatクリア効果があるので、その目的で使用するのは理にかなったことともいえる。難は、すぐその後に「display: block」と続けなければならないところが、パッと見には「?」であることだが。

最後に、モダンブラウザ・IE両対応のclearfix決定版をまとめておこう。
.clearfix:after { content: url(pixel.gif); display: block; clear: both; height: 0; } .clearfix { display: inline-block; } .clearfix { display: block; }

次回は、Mac版IE向けclearfixの決定版を探り、このシリーズの最終回としたい。