floatプロパティを指定した要素は親ボックスからはみ出し、後続のボックスの中に入り込む

最終更新日

指定した要素は親ボックスからはみ出し、後続のボックスの中に入り込むとマルチカラムレイアウトに使おうとすると不具合が発生します。ここでは、clearfixを使用した解決方法を記載します。

1、floatの問題を解決する

body要素の中には、p要素が2つあります。そして1つ目のp要素の先頭に画像が組み込まれていて、それに対してCSSで「float: left;」が指定されています。

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>floatプロパティ</title>
    <style type="text/css">
       img {
          float: left;
       }
    </style>
</head>
<body>
    <p id="paragraph1">
        <img id="image1" src="./img/春.jpg" alt="春の風景">
        段落1のテキストです。段落1のテキストです。段落1のテキストです。
    </p>
    <p id="paragraph2">
        段落2のテキストです。段落2のテキストです。段落2のテキストです。段落2のテキストです。段落2のテキストです。段落2のテキストです。段落2のテキストです。段落2のテキストです。段落2のテキストです。
    </p>
</body>
</html>
floatの問題を解決図

2、ボックスの背景とボーダーを表示させる

ボックスの状態がはっきりとわかるように、p要素に背景とボーダーを表示させます。次のCSSを追加します。段落1の中の画像がボックスからはみ出して、段落2の内部にまで入り込んでいることが確認できます。ボックスは常に四角形で、回り込む対象に応じて多角形に変化するわけではないため、floatを指定した要素はこのように親ボックスからはみ出る(そして、ほかのボックスに入り込む)仕様になっています。

<style type="text/css">
       img {
          float: left;
       }
       p {
        background:#ffff99;
        border: 7px solid #69c;
       }
</style>
ボックスの背景とボーダーを表示図

3、段落2でfloatをクリアする

clearプロパティでfloatを解除するとどうなるのか確認します。次のように、段落2でfloatをクリアする指定を追加します。段落2のボックスは、floatが指定されている画像の下に表示されるように変化しました。しかし、画像は段落1からはみ出したままです。画像を段落1のボックス内に収めるにはどうすればよいでしょうか?

<style type="text/css">
       img {
          float: left;
       }
       p {
        background:#ffff99;
        border: 7px solid #69c;
       }
       #paragraph2{
        clear: left;
       }
</style>
段落2でfloatをクリア図
図3:段落2のボックスがfloatが指定されている画像の下に表示される

4、clearfixを組み込む

裏技的な手法を使わずに画像を段落1のボックス内に収めるには、HTMLを含めてかなり大掛かりな修正が必要になります。clearfixと呼ばれるソースコードを追加します。画像とそれに回り込んだテキストの両方がボックスの中にきれいに収まっています。

<style type="text/css">
       img {
          float: left;
       }
       p {
        background:#ffff99;
        border: 7px solid #69c;
       }
       #paragraph1:after{
        content: ".";
        display:block;
        height: 0;
        clear:both;
        visibility: hidden;
       }
</style>
clearfixを組み込み図

5、clearfixの別バージョンを試す

clearfixには、細部で異なるバージョンが存在します。ここでは、clearfixをもっとシンプルにしてみます。clearfixのソースコードのうち、次の3か所を削除します。

#paragraph1:after{
        content: "";
        display:block;
        /* height: 0; ←削除 */
        clear:both;
        /*visibility: hidden;←削除 */
}
clearfixの別バージョンを試す

clearfixとは別の方法を試す

実は同様の効果は、clearfix以外でも得ることができます。overflowプロパティは、要素内容がボックスからはみ出るときにどのように表示させるかを指定するもので、値として初期値の「visible」以外を指定するだけでOKです。ただし、値に「scroll」を指定するとスクロールバーが表示されてしまうので、通常は「auto」または「hidden」が使用されています。

#paragraph1{
        overflow:auto;
}

解説

floatを指定した要素の全体を含むように親要素のボックスを拡張したい場合は、親要素の最後にブロックレベル要素を追加してそれにclearを指定します。そして、このようなCの状態を、新しい要素を追加することなくシンプルに実現するためのテクニックがclearfixというわけです。

解説
clearの指定場所による回り込み方の違い

clearfixの仕組み

ソースコード

まずセレクタ部分についている「:after」は、疑似要素の1つです。contentプロパティで内容として何かを追加するときに、○○○で指定したセレクタの要素内容の最後に挿入します。contentプロパティを指定されていますので、○○○の要素内容の最後に「.」を加えることになります。その後で、clearプロパティを指定するのですが、clearプロパティが指定できるのはブロックレベル要素になります。したがって、今回追加した「.」はブロックレベル要素にしなければなりません。それを行っているのが「dispalay=bolck;」です。「height: 0;」はボックスの高さを0にして見えないようにしています。「clear:both;」は左右両側のfloatをクリアする指定です。visibilltyプロパティの値として「hidden」を指定すると、ボックス全体が透明になって「.」が完全に見えなくなります。