複数カラムのブログテンプレートなどを作成するとき、一般的にはCSSのfloatプロパティを使ってレイアウトを行います。たとえば2カラムで左にサイドメニュー、右に記事本文というレイアウトは、以下のようなhtml&CSSになるでしょう。
HTML部 <div class="wrapper"> <div class="sidebar"> //サイドメニューエリア本文 </div> <div class="articlearea"> //記事本文 </div> </div> CSS .sidebar{ float : left; } .articlearea{ float : right; } |
カラムを包括する親ボックスの大きさが指定されており、各カラムが親ボックスの高さの値を超えないときには、特にレイアウト上の問題は起こりません。しかしながら、ブログのようにカラムの本文が可変長で親ボックスの高さを超えるケースが考えられるときには、カラムが親ボックスをはみ出て表示されてしまい、レイアウトが崩壊してしまいます。
これは、ボックス内でfloat指定されている要素の大きさが親ボックスの大きさを決める際に参照されないという特性によるものです。したがって最も仕様に適った解決は、floatさせた要素の後にclearプロパティでfloat解除した要素を設けることです。空のdiv要素やvisibilityプロパティをhiddenにしたhr要素、br要素がよく使われます。
HTML部 <div class="wrapper"> <div class="sidebar"> //サイドメニューエリア本文 </div> <div class="articlearea"> //記事本文 </div> //空divの場合 <div style="clear : both"></div> //非表示にしたhrまたはbr <hr class="clearfix" /> <br class="clearfix" /> </div> CSS .sidebar{ float : left; } .articlearea{ float : right; } .clearfix{ visibility : hidden; clear : both; } |
この方法はシンプルですが、ページのセマンティック(意味)としてはデザイン修正の為だけの無意味な要素をhtmlに加える事になるので好ましくありません。
そこで、無駄な要素を加えることなくレイアウト修正を行う、名前もそのまま”clearfix”というテクニックが開発されました。
HTML部 <div class="wrapper"> <div class="sidebar"> //サイドメニューエリア本文 </div> <div class="articlearea"> //記事本文 </div> </div> CSS //clearfixの追加部分 .wrapper:after{ content : ""; display : block; clear : both; } //IE6,7用 .wrapper{ zoom : 1; } .sidebar{ float : left; } .articlearea{ float : right; } |
CSSのafter疑似要素を使って、floatを解除する要素を無理矢理埋め込むという形です。この方法ならば、検索エンジンやアプリケーションがページのhtmlのみを取得する場合に、解釈の混乱をひきおこす無駄な要素が発生しません。IE用の追加部分については、独自仕様のhasLayoutというプロパティがtrueであれば子要素のfloatを親ボックスのサイズ計算に含めるという特性を利用しています。無害なレイアウト指定(zoom:1;やwidth:100%;など)であれば何でも良いのですが、ソースの意図を明確にする為にzoom:1;の指定をしている場合が多いようです。
ここまでがclearfixの説明です。先に述べた通り、floatを解除する要素を最後に加えるという解決方法ですね。
それに対して、親ボックスのoverflowプロパティを明示的にhiddenと指定することで、親ボックスのサイズ計算方法を変えるというテクニックもあります。overflowプロパティとは、ボックス内の要素がボックスのサイズを超えてしまった際の表示方法についての指定で、何も指定しない状態はvisible、つまりはみ出た部分も表示する指定になります。これをhiddenと指定した場合、はみ出す部分のみ非表示となると同時に、ボックスの高さの計算式にfloatさせた要素も含まれるようになります。
HTML部 <div class="wrapper"> <div class="sidebar"> //サイドメニューエリア本文 </div> <div class="articlearea"> //記事本文 </div> </div> CSS .wrapper{ overflow : hidden; //IE6,7用 zoom : 1; } .sidebar{ float : left; } .articlearea{ float : right; } |
場当たり的な対応ではありますが、セマンティックを汚染せずさらに簡単なので、こちらをバカの一つ覚えのように使ってしまって良いかもしれません。