float をした要素の親要素の背景画像などが途中で切れてしまうことがありますが、これは、その子要素を float 指定している場合、高さを認識しないため親要素は float する子要素の手前で高さを判断してしまうことによる現象です。そこで、float する子要素を含む親要素に、子要素の最後まで高さを認識させるための方法をメモしておきます。
簡単なサンプルを用意しましたので、ひとつづつ確認していきます。
1.サンプルを確認
[ HTML ]
画像を3枚 float:left; で並べる html をサンプルとして用意しました。
1 2 3 4 5 |
<div id="gallery"> <p><a href="#"><img src="images/img1.jpg"></a></p> <p><a href="#"><img src="images/img2.jpg"></a></p> <p><a href="#"><img src="images/img3.jpg"></a></p> </div> |
[ CSS ]
親要素の div#gallery に背景色 #cc9999 を指定。
子要素の p タグを float:left で左寄せにしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#gallery { padding: 10px; background-color: #cc9999; margin: 10px; height: auto; } p { width: 150px; height: 150px; margin: 0 10px 10px 0; border: 5px solid #FFF; float: left; box-shadow: 3px 3px 5px #CCC; } |
上記の記述の場合、どのように表示されるかというとこうなります。
floatをした<p>要素の高さが反映されず背景の色が途中で切れてしまっています。これを<p>要素の最後まで反映させるにはいくつか方法があります。
2.解決策を確認
大きく分けて解決策は2つあります。
解決策1: floatを解除した要素を追加する
ひとつは float させた要素の後に float を解除した要素を追加する方法があります。
[ HTMLを追記 ]
<p>要素の後に「一覧を見る」のリンクを追加します。
1 2 3 4 5 6 |
<div id="gallery"> <p><a href="#"><img src="images/img1.jpg"></a></p> <p><a href="#"><img src="images/img2.jpg"></a></p> <p><a href="#"><img src="images/img3.jpg"></a></p> <div class="all"><a href="#">一覧を見る</a></div> </div> |
[ CSSを追記 ]
1 2 3 |
.all { clear:both; } |
すると下記のように表示されます。
この方法でも問題はありませんが、float する要素の後に何も入れる要素がない場合も考えられます。
その際は、次の方法で対処が出来ます。
解決策2: 親要素にclearfixを指定する
:after という擬似要素と content プロパティを使って新しくボックスを追加し、これに clear をあてがう方法になります。
[ HTMLを追記 ]
親要素の<div id=”gallery”>に .clearfix 指定を追加します。
1 2 3 4 5 |
<div id="gallery" class="clearfix"> <p><a href="#"><img src="images/img1.jpg"></a></p> <p><a href="#"><img src="images/img2.jpg"></a></p> <p><a href="#"><img src="images/img3.jpg"></a></p> </div> |
[ CSSを追記 ]
1 2 3 4 5 6 7 8 9 10 |
.clearfix:after { content: " "; /* 新しい空要素を作る */ display: block; /* ブロックレベル要素にする */ clear: both; height: 0; visibility: hidden; } .clearfix { min-height: 1px; } |
簡単に説明すると親要素の#galleryの後に:after擬似要素を使って新たな要素を生成しています。サンプルでは、contentプロパティの値に「 (スペース)」を入れていますが、他の値でも問題はありません。さらにその要素をブロックレベル要素にしclear:bothでフロートを解除、height:0で高さなし、visibility:hiddenで非表示にしています。
IE6.7は擬似要素:afterがサポート対象外なので、「要素の幅か高さを指定した場合、floatした子要素の高さも含めて算出する」というIEのバグを利用して親要素の高さを反映させます。