2005年12月30日(金) コメント:2 トラックバック:0
「CSSのfloatプロパティは『回り込み』させるものである」とよく説明されますが、それは特定条件下での表示結果がそのように見えるだけであって、あまり正確ではありません。 「回り込み」という表現はfloatを使いこなすうえで、語弊になっていると思います。 floatとは、通常の流れ(normal flow)から取り除き、左(または右)に寄せるです。
- floatは「回り込み」ではない
-
<p> <img src="xxx.jpg" alt="floating image"> 「回り込む」テキスト </p>
このときimg要素を左にフロートさせた(float:left)なら、後続するテキストはimgの右側に「回り込み」ます。 これは確かに回り込みと呼べます。
では、ブロックレベル要素をフロートさせた場合はどうでしょうか。
<div style="width:100px; float:left;"> 左フロート </div> <div style="width:300px;"> 通常のテキスト </div>
div要素はブロックボックスを生成します。はじめのdivは100pxのボックスを作り左に寄ります。 先の例と同じように2番目のdivがフロートの右側にボックスごと「回り込む」ような気がしますが、実際はそうはなりません。 これが「回り込み」という表現がふさわしくないと感じる理由です。
ところが、IE6はまるで2番目のdivが左フロートの右側に回り込んだかのように表示してしまいます。 これはIEのバグですが、このバグのせいで、floatが回り込みさせるプロパティであるかのような誤解が生じているような気がします。
- floatは通常の流れから取り除く 1
-
通常の流れとはHTMLソースの順に上から積み重なるように要素が表示されていくことを言います。 フロートした要素はこの流れから取り除かれます。すなわち、フロートのあとにつづく内容はまるでフロートが存在しないかのように流し込まれます。
そうすると、フロートのあとにつづく要素とフロートが重なってしまうわけですが、このとき、
- フロートに重なるブロックボックスはフロートの背面に隠される(フロートの背景が透明なら、背面のブロックボックスが透けて見える)
- ただし、行ボックス(テキストの1行が入るボックス)はフロートと重ならないように幅が縮む
という規則があります(この点がposition:absoluteとの違いでもあります)。
img要素をフロートさせた例で言えば、フロートした画像は通常の流れから取り除かれ、内容は画像がそこに存在しないかのように流し込まれるが、 行ボックスはフロートと重ならないように縮んだために、テキストが画像の右に回り込んだかのように見えるのです。 div要素をフロートさせた例では、2番目のdivボックスはフロートの背面に隠され、divボックス内の行ボックスが縮んで、テキストがフロートの右側に流し込まれます。
このフロートの規則を直感的にイメージするには、文字どおり「浮かせる」と表現したほうがfloatの本質により近いかと思います(インラインボックスがフロートと重なる場合は、フロートの前面に表示されるので、「浮いている」というのも厳密ではないのですが)。
- floatは通常の流れから取り除く 2
-
1pxの実線を指定したdiv要素内にimg要素があるとします。
<div style="border:1px solid black"> <img src="xxx.jpg" alt="floating image"> <img src="xxx.jpg" alt="floating image"> </div>
imgをフロートさせ、ボックス内の要素がすべてフロートになった場合を考えます。 フロートは通常の流れに属さないので、このdivは中身が無いものと見なされ、高さが確保されません(height=0になる)。 よって、2つの画像を枠で囲んだつもりでも、ボーダーが画像を囲むことはありません。
ちなみにこのdivにwidthで幅を指定すると、IE6はフロートした画像を囲むようにボーダーを表示しますが、バグなので気にしては駄目です。
- floatを使った段組
-
ブログでよくあるような段組レイアウトを実現するためにfloatが使われていますが、これはフロートの振る舞いの厳密な規則にあるように、 「左フロートにつづく左フロートは、先の左フロートより右側になければならず(右フロートの場合は左右逆に読み替え)、フロートは可能な限り上に配置しなければならない」という規則を利用しているのです。 だから、左右のカラムの両方にfloatを指定するわけです。
2カラムレイアウトの解説でよくある、「左のカラムはfloat:leftで左に回り込ませ、右のカラムはfloat:rightで右に回り込ませる」という表現は、ちょっと違うなぁと思います。
floatは確かにやっかいですが、最近のブラウザなら、わりとちゃんと(仕様どおりに)解釈してくれます。 floatが難しいのは、制作者が正しい仕様を知らないか、IEのバグのせいです(あからさまに仕様を無視するのは、もはやIEくらいです)。 floatを使いこなすには、仕様書やCSS2リファレンスなどで詳しい仕様を学び、そのうえで、バグを回避する必要があります。
コメント(2件)
”floatは通常の流れから取り除く”この考え方を使ったら、テキスト読んでも分からなかった"float"の概念がとても良く理解できました。本当にありがとうございます。
このコメントは管理者の承認待ちです