Web標準普及プロジェクト

height: n%;の正しい仕様

CSSでは例えばheight: 100%;と書いた場合、実際にどういった高さとなるかご存じでしょうか? この算出値は親要素に左右されるのですが、 よく勘違いされている方がいるので正しい仕様を紹介しておこうと思います。

なおここでは話を分かりやすくするために通常フローの場合であることを前提に記述しています。 通常フローでは無い要素の場合、親要素を包含ブロックに読み替えてください

親要素の高さが明らかな場合

多くの方はこの場合の仕様のみをご存じのはずです。 説明する間でもなく、親要素の高さのn%がその要素の高さとなります。

例えばheight: 300px;の要素の要素が height: 50%;だった場合、その算出値は150pxになります。

親要素の高さが'auto'の場合

heightプロパティの初期値はautoです。 つまり、明示的にheight: auto;と指定された要素、 もしくはheightプロパティが無指定の要素の子要素が height: n%;となっていた場合、どうなるかご存じでしょうか? CSS2の仕様書には次のように記述されています。

<percentage>

包含ブロックの高さに対する割合を指定する。 包含ブロックの高さが明示されておらず、内容領域の高さに依存していれば、'auto'として解釈する。

つまり、親要素、子要素共に算出値は'auto'となり、 内容の大きさに依存することになります。

これはbody要素の子要素のtable要素やiframe要素等に<percentage>で高さを指定すると、 その算出値がautoとなることを意味しています。

実際に次の構造のHTML文書にスタイル指定を行ってどのようにすれば意図通りの表示になるのか見てみましょう。

<html>
    <head>
        (略)
    </head>
    <body>
        <pre>
            このpre要素の高さを100%に指定して
            ブラウザの表示面の高さとなるかどうかテストします。
        </pre>
    </body>
</html>

まずはよくうまくいかないと言われるパターンです。

pre{
    height: 100%;
    border: red dashed 10px;
}

この場合、Mozilla、Opera7、Windows版InternetExplorer6において、 HTML4.01 Strictではpre要素の高さがautoと算出され、 仕様通りに内容の高さを含めるのに十分な高さになっています。

それに対してHTML4.01 Transitional(URIの記述無し)の場合、 ブラウザの表示面を親要素の高さであると拡大解釈して、 pre要素の高さが表示面全体に広がっています。

ではこれらのブラウザで標準準拠モードで表示面全体に高さを広げたい場合、 どのようにすれば良いのでしょうか? CSS2の仕様書には次のような記述があります。

ルート要素の包含ブロック(これを初期包含ブロックと呼ぶ)はUAが定める。

少し曖昧な記述ですが、表示面をルート要素の包含ブロックとすることが望ましいように思われます。 そして、Mozilla、Opera7、Windows版InternetExplorer6ではそのように実装されているようです。 つまり、上記のスタイル指定以外に次の指定を追加します。

html,body{
    height: 100%;
}

HTML文書のルート要素はhtml要素です。 そして、pre要素とhtml要素の間にはbody要素がありますので、 これら全てのheightを100%としなければいけません。