CSSでfloatを解除する方法のまとめ
CSSのfloatを解除(クリア)する方法をまとめてみました。
以前、floatを解除するテクニックとして以下の記事をエントリーしたのですが、その後色々なテクニックがあることに気がつきました。
ということで、そもそものfloatの問題(というか仕様)と、その対処方法についてネットで調べた情報を一通りまとめました。
1.floatにより親要素の高さが出なくなる(=背景がなくなる)問題
親要素の中にある子要素にfloatプロパティが設定されていると、内容をもたない親要素の高さが0になるという仕様になっています。
例えば、次のCSSとHTMLを例にします。
<style>
#container {
width: 200px;
background: #ddd;
}
.box {
width: 25px;
margin: 10px;
padding: 10px;
border: 1px solid #999;
background: #fff;
float: left;
}
#footer {
width: 200px;
background: #aaa;
}
</style>
<div id="container">
<div class="box">foo</div>
<div class="box">bar</div>
</div>
<div id="footer">footer</div>
期待するのは次のような表示です。
が、実際には次のように親要素の高さが出なくなります。
2.空要素を挿入してfloatを解除する
floatを解除するためのもっとも原始的な方法がこれです。
…前略…
<div id="container">
<div class="box">foo</div>
<div class="box">bar</div>
<div style="clear: both"></div>
</div>
<div id="footer">footer</div>
floatしている最後の子要素の後方に空の要素をいれ、その要素にclearプロパティを与えることでfloatが解除できます。
clearプロパティを設定することで、先行するfloatプロパティを解除します(詳細は別途追記予定)。
3.「:after」擬似要素でflaotを解除する
2項の方法をCSSで実現したのが「:after」擬似要素による方法です。これが「clearfix」と呼ばれるテクニックです。
<style>
…前略…
.clearfix:after {
content: '';
display: block;
clear: both;
}
.clearfix {
zoom: 1; /* for IE6/7 */
}
</style>
<div id="container" class="clearfix">
<div class="box">foo</div>
<div class="box">bar</div>
</div>
<div id="footer">footer</div>
floatした最後の子要素の後続の要素(つまりafter擬似要素)にブロックレベル要素の空のコンテンツを与え、clearプロパティでfloatを解除します。
やっていることは2項と全く同じで、2項でなぜspan要素ではなくdiv要素を使っているかもこのCSSから推測できると思います。
ちなみに、以前はNetscapeやMacIE対応のため、もう少し複雑な設定になっていました(下)。
.clearfix:after {
content: '';
display: block;
clear: both;
height: 0;
visibility: hidden;
}
.clearfix {
zoom: 1; /* for IE6/7 */
}
が、それらのブラウザがほとんど使われなくなった現在、簡略した設定でも大丈夫ではないかと思われます。
clearfixの語源も調べてみましたが、それらしいものは見つかりませんでした。おそらく「clearプロパティでレイアウトを修正または固定(fix)する」という意味じゃないかと思います。
4.擬似要素でfloatを解除する
3項の発展系のようです。before擬似要素の設定により上マージンの崩れを防ぐようです。class名も少し短くなっていて「micro clearfix」と呼ばれています。
3項の設定が複雑なときのものであればこちらの設定が簡略化されたようにみえるはずですが、今となってはどちらも大差ありません。
<style>
…前略…
.cf:before, .cf:after {
content: '';
display: table;
}
.cf:after {
clear: both;
}
.cf {
zoom: 1; /* for IE6/7 */
}
</style>
<div id="container" class="cf">
<div class="box">foo</div>
<div class="box">bar</div>
</div>
<div id="footer">footer</div>
「display: table;」はテーブルとして表示させるための設定です。「display: block;」に変更しても効果は同じようです(意味は違いますが)。
元記事のコメントに「IEが不要であれば1行にできるよ」という技もありました(下)。
.cf:after { content:''; display:table; clear:both; }
5.overflowプロパティでfloatを解除する
最近主流らしいのが、親要素に対してoverflowプロパティを与えてfloatをクリアする方法です。
3・4項よりもだんぜんに記述量が少なく、class属性を設定する必要もありません。
<style>
#container {
width: 200px;
background: #ddd;
overflow: hidden;
}
…後略…
</style>
<div id="container">
<div class="box">foo</div>
<div class="box">bar</div>
</div>
<div id="footer">footer</div>
が、floatがクリアされる理由が分からないまま使っている方も多いのではないでしょうか。
6.overflowプロパティで回り込みが解除される理由
ということで調べてみました。
これがこのエントリーで一番書きたかったことですが、overflowプロパティで回り込みが解除される理由は、CSS2.1の10.6.6に記載があります。
10.6.6 Block-level, non-replaced elements in normal flow when 'overflow' does not compute to 'visible'; 'inline-block', non-replaced elements; and floating, non-replaced elements(邦訳)
'overflow'の算出が'visible'ではない、通常フローの非置換ブロックレベル要素(ただし'overflow'プロパティの値が表示域へと伝播されていなければ)~中略~'height'が'auto'なら、その高さは要素の子孫に依存する。
つまり、親要素のheightが「auto」の場合、overflowプロパティの値に「visible」以外を設定すれば、その高さは要素の子孫に依存することになる、という仕様になっているようです。
言い換えると、最初のサンプルで親要素の高さが出ないのは、「overflow: visible;」がデフォルトで設定されているためです。
この方法ではfloat自体はクリアされていないという理解ですが、認識が間違っていたらどこかでつぶやいてください。
7.overflowプロパティを使った場合の問題と対処
overflowプロパティを使うと、その設定が子要素にも適用されます。また「Firefoxの印刷バグもある」という記事もみかけました。
ということで、状況に応じて上記のテクニックを使い分けるといいかもしれません。
ちなみに印刷時のバグは、以下のようにスタイルシートを分けることで回避できるかもしれません。
<link rel="stylesheet" href="style.css" type="text/css" media="screen,tv" />
<link rel="stylesheet" href="print.css" type="text/css" media="print" />
8.参考サイト
参考サイトは下記です。ありがとうございました。
- clearfixするためにoverflow:hidden;を使って困ったことがある人へ
- overflow:hidden;とclearfix
- A new micro clearfix hack
- フロートの性質
- YouTube動画にキャプションをつけてテキストを回り込ませる方法
- 画像を下揃えにしてテキストを回り込ませる方法
- style要素にCSSの擬似要素は記述可能か?
- position:relativeを設定すると他の要素がずれる場合の対処
- CSSでタブ切り替えする方法
- :target擬似クラスのまとめ
- CSSでヘッダを固定したスクロールテーブルを作る方法
- レスポンシブウェブデザインで画像を縮小する方法
- disabledなボタンのhoverのスタイルを無効にする方法
- HTML要素を別の要素を基点にしてCSSで絶対配置する方法
- :not擬似クラスでCSS3のサポートをチェックする方法
- :checked擬似クラスでチェックボックスに連動して要素を表示させる方法
- ol要素の入れ子で親の番号を子に割り当てる方法
- チェックボックスやラジオボタンを大きくする方法
- CSSで中央に配置する方法