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>
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>
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>
5、clearfixの別バージョンを試す
clearfixには、細部で異なるバージョンが存在します。ここでは、clearfixをもっとシンプルにしてみます。clearfixのソースコードのうち、次の3か所を削除します。
#paragraph1:after{
content: "";
display:block;
/* height: 0; ←削除 */
clear:both;
/*visibility: hidden;←削除 */
}
clearfixとは別の方法を試す
実は同様の効果は、clearfix以外でも得ることができます。overflowプロパティは、要素内容がボックスからはみ出るときにどのように表示させるかを指定するもので、値として初期値の「visible」以外を指定するだけでOKです。ただし、値に「scroll」を指定するとスクロールバーが表示されてしまうので、通常は「auto」または「hidden」が使用されています。
#paragraph1{
overflow:auto;
}
解説
floatを指定した要素の全体を含むように親要素のボックスを拡張したい場合は、親要素の最後にブロックレベル要素を追加してそれにclearを指定します。そして、このようなCの状態を、新しい要素を追加することなくシンプルに実現するためのテクニックがclearfixというわけです。
clearfixの仕組み
まずセレクタ部分についている「:after」は、疑似要素の1つです。contentプロパティで内容として何かを追加するときに、○○○で指定したセレクタの要素内容の最後に挿入します。contentプロパティを指定されていますので、○○○の要素内容の最後に「.」を加えることになります。その後で、clearプロパティを指定するのですが、clearプロパティが指定できるのはブロックレベル要素になります。したがって、今回追加した「.」はブロックレベル要素にしなければなりません。それを行っているのが「dispalay=bolck;」です。「height: 0;」はボックスの高さを0にして見えないようにしています。「clear:both;」は左右両側のfloatをクリアする指定です。visibilltyプロパティの値として「hidden」を指定すると、ボックス全体が透明になって「.」が完全に見えなくなります。