IE6の呪縛 フロート(float)を正しく理解する

フロート(float)について、スタイルシートリファレンスなどを引くと、「float: 左または右に寄せて配置する」などと簡単に書いてありますが、厳密には違います。まずここで勘違いが起きます。
そして、IE6というクソブラウザは、フロートの仕様に対するバグが甚だしく、この勘違いをさらに加速させてきました。
そのせいで、いまでもフロートに苦しめられている人は多いのではないでしょうか?
今回はこのフロートについて正しく理解していきたいと思います。

フロートは「左または右に寄せて配置する」だけではない

<div style="float: left; width: 100px;">
	float: left;
</div>
<p>
	text
</p>

後続の要素に影響を与えているので、フロートは「左または右に寄せて配置する」だけではありません。

フロートは「回り込み」でもない

<div style="width: 100px; float: left">
	float: left;
</div>
<div style="width: 100px;">
	text
</div>

さきほど、後続のP要素は右に回りこみましたが、このdiv要素では回りこみは発生しません。
フロートは「回りこみ」だけでもありません。

※IE6では回りこんだように表示されますが、これはバグです。

フロートとは「浮動化させる」こと

「float」を英和辞書で引いてみると、「浮く、浮き上がる」と出ます。
そう!フロートとは「浮動化させる」ことなのでした。

基本的な3カラムレイアウトを組みながら検証していきます。

> HTML

<div id="warpper">
	<div id="header">
	</div>
	<div id="container">
		<div id="sidebar">
		</div>
		<div id="content">
		</div>
	</div>
	<div id="footer">
	</div>
</div>

間違ったパターン その1

#warpper {
	width: 300px;
}
#header {
	height: 50px;
	background: #FF99CC;
}
#container {
	background: #999;
}
#sidebar {
	float: left; /* 左にフロート */
	width: 100px;
	height: 100px;
	background: #66CC99;
}
#content {
	width: 200px;
	height: 50px;
	background: #CCC;
}
#footer {
	height: 50px;
	background: #6699FF;
}

なんじゃこりゃ~!

でも当然のことです。

通常フローでは、ブロックボックスは常に縦方向に配置されていきます。
ところが、フロートされたボックスは浮いている、つまり通常フローから逸脱しているので、他のボックスは、浮動ボックスが”ないもの”として配置されます。

つまりこうなっている↓

視覚化すると分かりやすいですね。

間違ったパターン その2

#warpper {
	width: 300px;
}
#header {
	height: 50px;
	background: #FF99CC;
}
#container {
	background: #999;
}
#sidebar {
	float: left; /* 左にフロート */
	width: 100px;
	height: 100px;
	background: #66CC99;
}
#content {
	float: right; /* 右にフロート */
	width: 200px;
	height: 50px;
	background: #CCC;
}
#footer {
	height: 50px;
	background: #6699FF;
}

うわ!もっとひどくなった!

はい、つまりこういうことです↓

なるほどなるほど。「フロート = 浮動化」ってことで完全理解!と思うのはまだ早いです。

ここで、浮動化したボックスと同じ行にテキストを入れてみます。

<div id="warpper">
	<div id="header">
	</div>
	<div id="container">
		<div id="sidebar">
		</div>
		<div id="content">
		</div>
		text
	</div>
	<div id="footer">
	</div>
	</div>

なにこれ?またもや理解不能…

CSS2では、「ブロックボックスは浮動ボックスの背面に、インラインボックスは前面に配置される。」と定義されています。
つまり、ブロックボックス内のテキストは、見えない”匿名インラインボックス”を形成するので、浮動ボックスの前面に配置される、つまりインラインボックスは、浮動ボックスが”あるもの”として配置されます。

フロートの解除

clear プロパティによるフロートの解除

フロートを解除する方法として、clear プロパティを設定している人は多いでしょう。

#warpper {
	width: 300px;
}
#header {
	height: 50px;
	background: #FF99CC;
}
#container {
	background: #999;
}
#sidebar {
	float: left;
	width: 100px;
	height: 100px;
	background: #66CC99;
}
#content {
	float: right;
	width: 200px;
	height: 50px;
	background: #CCC;
}
#footer {
	clear: both; /* フロートを解除 */
	height: 50px;
	background: #6699FF;
}

一見これでよさそうですが、よーく見てください。
浮動ボックスを囲んでいる親ボックス(container)は、依然として浮動ボックスを認識していません。
包含している要素がないので、高さは0です。

※IE6ではフロートした要素を囲むようにボーダーを表示しますが、これもバグです。

「clearfix」によるフロートの解除

親ボックスに「overflow: hidden;」を設定します。
こうすることで、包含する浮動ボックスの高さも含めた高さを算出してくれます。

#warpper {
	width: 300px;
}
#header {
	height: 50px;
	background: #FF99CC;
}
#container {
	overflow: hidden; /* 簡易的なclearfix */
	background: #999;
}
#sidebar {
	float: left;
	width: 100px;
	height: 100px;
	background: #66CC99;
}
#content {
	float: right;
	width: 200px;
	height: 50px;
	background: #CCC;
}
#footer {
	height: 50px;
	background: #6699FF;
}

これが正解。

以前は、複雑なclearfixが使われていましたが、こちらの方が簡単でいいと思います。

ちなみに、IE6でもclearfixが機能するようにするには、「zoom: 1;」も設定すればよいのですが、フロートに対する勘違いの元凶、いまだに多くの人を苦しめているクソブラウザ、そして続々とサポートを打ち切られている古すぎるブラウザに配慮すべき状況があったら、それこそ最悪な気分ですねwww

まとめ

・フロートとは、通常フローから逸脱させ、浮動化させること。
・フロートボックスは、可能なかぎり左/右に配置される。
・ブロックボックスはフロートボックスの背面に、インラインボックスは前面に配置される。
・clear プロパティとclearfixで、フロートの解除を行う。

以上をよく理解しておけば、もうフロートでつまづくことはなくなると思います。たぶん

より深くフロートの厳密な配置ルールを知りたい方はこちら→ 視覚整形モデル/フロート

Comments

  • Nyaos より:

    floatは「左または右に寄せて配置する」ではなく、本当に「上に浮遊(float)している」。
    まさに図の通りですよね。

    レイアウトを学ぶ上で最初の鬼門ですね。
    さっさとfloatにかわる何かを作って欲しいです。

コメントを残す