Web標準普及プロジェクト

heightプロパティの注意点〜内容がfloat要素の場合

heightプロパティの注意点〜内容が大きい場合」で紹介した通り、 Windows版IEにはoverflowに根本的な解釈ミスがあるため、様々なCSS仕様に対して悪影響を持っています。 今回紹介するものもWindows版IEのバグのために誤解されていることの多いfloat関係の問題です。 このfloatという考え方は従来のHTMLで指定できたalign属性(の従来のブラウザでの表示結果)とは若干異なっているので注意してください。

heightのauto(初期値)の算出方法

heightプロパティの初期値はautoです。 この値ならブロックレベル要素でも内容を全て収めるのに必要な高さを自動的に算出して設定していそうですが、 そう考えるのは少し誤解があるかもしれません。 まずは次の例を見てみましょう。

<div style="border:solid 1px blue;width:160px;height:auto;">
    このテキストは先に出現します。
    <div style="border:solid 1px red;width:80px;height:80px;float:left;">
        このテキストはフロートするブロック内に出現します。
    </div>
    このテキストは後に出現します。
</div>
このテキストは先に出現します。
このテキストはフロートするブロック内に出現します。
このテキストは後に出現します。

ちなみに筆者の環境ではこのように表示されました。

IE6(Win)
Mozilla(Win)
Opera6.03(Win)

これもWindows版IE以外のブラウザOperaの表示が正しい表示です。 正常なブラウザではheight値がautoにも関わらず、赤い枠線のdiv要素の存在が無視されて外側の青い枠線のdiv要素の高さが決定されます。

10.6.3 通常のフローにあるブロックレベル非置換要素及び浮動非置換要素

'top','bottom','margin-top'又は'margin-bottom'が'auto'である場合,計算値は0とする。 'height'が'auto'である場合,高さは,要素がブロックレベルの子供をもつかどうかに依存する。 要素が行内レベルの子供だけをもつ場合は,高さは,最上部の行ボックスの上辺から最下部の行ボックスの下辺までの距離とする。 要素がブロックレベルの子供をもつ場合は,高さは,最上部ブロックレベルの子ボックスの境界上辺から, 最下部ブロックレベルの子ボックスの境界下辺までとする。考慮するのは通常のフローにおける子供に限る。 すなわち,浮動ボックス及び絶対位置決めボックスは無視され,相対位置決めされたボックスは, 位置指定がないものとして考慮される。子ボックスが匿名ボックスであってもよい点に注意すること。

つまり、height:auto;の場合にブラウザが必要な高さ算出に参考にするのはfloatしていないインライン要素とブロックレベル要素の高さであるということです。

浮動要素の高さもheightに含めさせる方法

さて、それではIE6が表示したように、floatしている要素も含めて親要素の高さをブラウザに設定させる時はどのようにするのでしょう。 実際にページをデザインする上ではこちらの方がよく使われる手法です。

これは簡単で、floatを解除してやれば、それ以降に続く要素はfloatしたブロックの下に回り込むようになります。 つまり、内容の高さに対して影響力が出てくる、ということです。具体的には次のようにします。

<div style="border:solid 1px blue;width:160px;height:auto;">
    このテキストは先に出現します。
    <div style="border:solid 1px red;width:80px;height:80px;float:left;">
        このテキストはフロートするブロック内に出現します。
    </div>
    このテキストは後に出現します。
    <br style="clear:both;">
</div>
このテキストは先に出現します。
このテキストはフロートするブロック内に出現します。
このテキストは後に出現します。

注意

この<br style="clear:both;">という指定は実は仕様違反かもしれません。 br要素はCSS2では表現できない特殊な要素ですが、CSS2仕様書でのHTML4.0の定義例でbr要素はインライン要素となっています。 clearプロパティ自体は本来、ブロックレベル要素にしか適用されません。 しかしブラウザはbr要素でのclearプロパティを容認するようです。 これはHTML4.01 Transitionalでclear属性が存在したためではないかと思われます。 今回は空のブロックレベル要素でclearに指定を行うのもあまり適当ではないと考え、br要素で指定しました。

[訂正] float要素の上端の配置位置について

本題の親要素の高さに関してはMozilla、Operaの表示が正しく、Windows版IEの表示は間違っているという結論は変わりありません。 しかし、以前の版でここに掲載していたfloat要素の配置位置に対する解釈が間違っていました。 以前の記事で、Operaの解釈を仕様の範囲内だと書いていましたが、実際にはそうあるべきであり、 Windows版IEとMozillaの配置位置は単にバグで、正常な配置ではありませんでした。

floatの配置仕様の6番目に

要素の浮動ボックスの外上辺は, ソース文書の中のそれ以前の要素によって生成されたボックスを包含する行ボックスの上辺より高くてはならない。

と、書かれています。

先行するインライン要素(または匿名インライン)の最後の行(インラインボックス)の上端とfloatした要素の上端(マージン辺)が一致するように配置しなくてはいけません。 Mozillaではこの問題をBug-org 50630 [FLOAT] float should be as high as previous line boxで扱っています。