floatしたボックスを含む親ボックスの高さの算出
この背景色(画像)現象は僕も頻繁に遭遇するものでした。後続の要素で回り込みを解除してやれば良いわけですが、clearプロパティを指定するボックスが、floatプロパティを指定したボックスと同じ親ボックスに包括されていない場合には、解決に至りません。
例えば、
#parent { width: 500px; background: #000; padding: 10px; }
#box1 { float: left; width: 200px; background: #ccc; }
#box2 { float: right; width: 200px; background: #ccc; }
#box3 { clear: both; }
上記のスタイルを前提に、以下のようにHTMLを記述した場合には問題ありません。
<div id="parent">
<div id="box1">左にfloat</div>
<div id="box2">右にfloat</div>
<div id="box3">回り込みの解除</div>
</div>
ですが、次の例ではダメだということになります。
<div id="parent">
<div id="box1">左にfloat</div>
<div id="box2">右にfloat</div>
</div>
<div id="box3">回り込みの解除</div>
前者の場合、#parent内に回り込みを解除できる#box3のような適当な要素がない場合には困ってしまいます。そんなときは、徒書でも示されているように、:after擬似要素とcontentプロパティを用いて、親ボックスの最後に、(ここでいうところの#box3の代わりとなる)内容を生成してやり、それに対してclearプロパティを指定する方法が特に有効だと思います。
後者の場合、回り込みは解除できているものの、clearプロパティを指定したボックス#box3が、#parent内にないので、うまく背景が反映しないわけですが、この場合、#parentにoverflow: auto;とスタイルを追加してやることで、問題を解決できるようです。ただ、この記述をすることで、なぜ#parentの背景が反映するのか(#parentの高さがfloatプロパティを指定した#box1と#box2の最下辺まで及ぶのか)、その仕組みはつかめていません。
また徒書では、上の現象はFirefoxで主に発生するものとして、Operaの場合、IE拠り(#parent内に#box3がなくても背景が反映する)としていますが、Operaのバージョン7とバージョン8では、挙動が異なりまして、バージョン7ではIE拠り、最新のバージョン8ではFirefox拠りの表示を行います。
さらに、SafariやMacIEの場合も、FirefoxやOperaバージョン8拠りの挙動のようです。(ちなみに、#parentにoverflow: auto;と指定することで、Safari、MacIE、Operaバージョン8でも同様に問題を解決できます。)
WinIEとその他のブラウザで、どちらが仕様上正しいのかは、残念ながら僕もはっきりとはわからず終いです。「WinIE以外がそうだから多数決でそっちが正しい!」というのは乱暴ですが、Operaがバージョンアップとともに、わざわざ他のモダンブラウザに合わせて挙動を変更してきたということは、何かしらの根拠があるのではないかな、と思えます。
関係ありそうなところとしては、CSS level2仕様書のfloatの項に
Since a float is not in the flow, non-positioned block boxes created before and after the float box flow vertically as if the float didn't exist.
とありまして、該当する日本語訳を読むと、
浮動体は流れの中にないので,浮動ボックスの前後で生成される位置決めされないブロックボックスは,浮動体が存在しないものとして,上下方向に流し込まれる。
となっているところ。このあたりのブラウザによる解釈の差が、親ボックスの高さの算出にも影響しているのかな、とも思っています。
※追記:やっとわかった。ちゃんと書いてありました。以下邦訳版から引用します。
要素がブロックレベルの子供をもつ場合は,高さは,最上部ブロックレベルの子ボックスの境界上辺から,最下部ブロックレベルの子ボックスの境界下辺までとする。考慮するのは通常のフローにおける子供に限る。すなわち,浮動ボックス及び絶対位置決めボックスは無視され,相対位置決めされたボックスは,位置指定がないものとして考慮される。
※さらに追記:overflowプロパティを指定して、親ボックスの高さがフロートの子ボックスの下辺まで及ぶのは、CSS2.1の勧告候補に基づいているようです。CSS2.1では、浮動ボックスが無視されるのは、Block-level non-replaced elements in normal flow when 'overflow' computes to 'visible'
とあるように、overflowプロパティの値にvisibleである場合に限定されていました。
「opera float div」でググってきました。
積年の問題が解決できました。ありがとうございます。
前にやっていたこと:
.parent:after {
content: ".";
display: block;
height: 0px;
clear: both;
visibility: hidden;
margin:0px;
padding: 0px;
}
↑これだとOPERA8で親ボックスの下部に謎のマージンができていました。ご説明の通り
.parent:after {
display:block;
margin-top:-1px;
height:1px;
content:"";
clear:both;
}
としたら解決!
投稿者 藤田 健 : December 15, 2006 03:38 PM
ほとんどのブラウザで、背景を表示させる方法です。
clearさせるための要素がなくてもできます。
http://kikky.net/pc/float_bg.html
投稿者 (ai) : August 16, 2007 02:48 PM
コメントありがとうございます。本エントリーでも追記の部分でそのあたりに触れています。
CSS2.1の仕様に基づいたものではありますが、overflow:autoやhiddenは危険なケースも多い(特に印刷時など)です。今はclearfixでクリア用のボックスを生成させるテクニックを用いたほうが安全だという結論に至っています。
投稿者 kawachi : August 16, 2007 09:36 PM