CSSでfloatを解除する方法のまとめ

CSSでfloatを解除する方法のまとめ

Posted at March 28,2013 12:55 AM
Tag:[CSS, float]

CSSのfloatを解除(クリア)する方法をまとめてみました。

floatによる親要素の高さが出ないイメージ

以前、floatを解除するテクニックとして以下の記事をエントリーしたのですが、その後色々なテクニックがあることに気がつきました。

CSS の after 擬似要素で回り込みを解除する

ということで、そもそもの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.参考サイト

参考サイトは下記です。ありがとうございました。

関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)