背景を下までずずーっと伸ばしたい時は、bodyにbackground-imageを指定すればよいですが、div等に指定した背景やborderをページの下まで伸ばしたい時は、以下のようにします。
<body>
<div id="Container">高さ100%</div>
</body>
*{
margin:0;padding:0;
}
html{
height:100%;
}
body{
height:100%;
}
#Container{
height:100%;
min-height:100%;
width:80%;
background:Khaki;
border-right:1px solid red;
}
body > #Container{
height:auto;
}
以下、なぜこれで実現できるのかの解説と疑問点。とても長い。
div#Containerの高さをmin-height:100%にしてやることで、最低限100%ーつまり、ページの下までの高さを確保する。min-height:100%なので、それ以上、中の要素が高さを持っても、どんどん伸びるという仕組みです。
しかし、IE6なんかはmin-heightに対応していないため、代わりにdiv#Containerにheight:100%を指定してやります。これで同じように最低限100%が確保される。ただ、このheight:100%には、他のブラウザでまずいことがあって、ウィンドウの高さを越えてしまうと、そこで背景がぶっちぎられる現象が起こってしまうということです。
以下はFirefox2でのキャプチャ。

なぜ?というと、div#Containerには100%を指定したので、ブラウザの表示領域一杯分の高さが指定されたが、それを超えてしまう分は、オーバーフローして切れてしまうからです。例えば、
<div style="height:15px;background:Khaki">hogehoge<br />hogehoge</div>
と、書いたとします。CSS2を正しく実装しているブラウザは、こんな風に見える。

ブロック要素の高さは、heightで明示的に指定した場合、内包する要素の高さに関係なく、オーバーフローします。(ただし、テーブルのセルは例外) これはCSS2の正しい動作。しかし、IE6以下ではこんな風に見える。

テーブルのセルみたいに伸びる。IEは、内用する要素の高さが、親ボックスを超えてしまっても、オーバーフローするのではなく、その分、親ボックスの高さを伸ばしてくれるという特殊な動作をするわけです。この、IEの独自の動作(っていうかバグだけど)を利用することで、div#Containerにheight:100%で、下まで伸ばすことができるわけです。やったー
と、その前に、この状態では、IEはオッケーなのですが、他のブラウザは、ちゃんと、height:100%でページ一杯まで伸ばしてくれるものの、それを超えた分はちぎられてしまう問題が残ってました。FirefoxらはCSS2に忠実なので。それを解決するのがコレ
body > #Container{
height:auto;
}
body直下の#Containerにheight:auto;を指定してやることで、さっき指定したheight:100%を解除してあげるのです。IE6はこの子供セレクタに対応していないので、IE6以下は、div#Containerにheight:100%が指定され、FirefoxやOpera等の頭いいブラウザには、div#Containerにmin-height:100%が指定された状態になりました。これで、IE対策のためにぶっちぎられてしまった現象は解消された!下までdiv#Containerが伸びましてめでたしめでたしと。
これで納得した人はコレで終わりです。
でも、自分は、以下の指定が全く意味不明だった。
html{
height:100%;
}
body{
height:100%;
}
なんじゃこりゃと。さらにコレ抜かしたら実現できなくなるし。下はhtml,body{height:100%}を抜かしたもの。

これを理解するには、まず、CSSのheightとは何なのかを理解する必要がある。
以下は、CSS2の仕様書より、heightについて一部抜粋。
10.5 Content height: the 'height' property
<percentage>
Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), the value is interpreted like 'auto'.
heightには、数字かパーセントか、autoを取れます。デフォルトはauto。autoだと、中身がふえりゃその分増える。中身が増えたら伸びてくれなったらまぁ困りますわな。数字の場合はその高さで固定。100pxとか10emとか。もういっこ、%というのが曲者で、ざっと訳すと、
heightに%を指定した場合、その要素を含む、親ボックスの高さに基づいた計算が行われる。もし、その親ボックスの高さが明確に指定されていない場合、%を指定してもautoと同じように扱われる。(そりゃ親ボックスのコンテンツの高さって意味じゃなくて、明確に例えば100pxとか指定されてないとダメ)
みたいなことを言っている。
だから、div#Containerのheightやmin-heightに100%を指定したところで、そのすぐ上の親であるbodyの高さは何も指定されていなければ、bodyの分まで高さ一杯にはならないのです。height:autoと同じなのです。だから、bodyに100%を指定してあげる。これで、親の高さが明示され、div#Containerの高さがbody一杯分に確保される。
同じように、bodyの親であるhtmlにも高さが指定されていないとだめだよねということで、htmlにも100%を指定してあげる。これで根っこから高さを明示してあげたので完成!
と、ここで納得した人はコレで終わりです。
だけど、htmlに100%って何よ。htmlってルートの要素なんだから、それにも高さを指定してあげないとダメなわけ?コレって意味わかんなくない?htmlの親なんて何も無いでしょ。htmlにheight:100%って、何の100%なわけ?
コレを理解するには、viewportって言う概念を理解する必要がある。以下、CSS2の仕様書より、viewportについて抜粋。
9.1.1 The viewport
User agents for continuous media generally offer users a viewport (a window or other viewing area on the screen) through which users consult a document. User agents may change the document's layout when the viewport is resized (see the initial containing block). When the viewport is smaller than the document's initial containing block, the user agent should offer a scrolling mechanism. There is at most one viewport per canvas, but user agents may render to more than one canvas (i.e., provide different views of the same document).
9.1.2 Containing blocks
In CSS2, many box positions and sizes are calculated with respect to the edges of a rectangular box called a containing block. In general, generated boxes act as containing blocks for descendant boxes; we say that a box "establishes" the containing block for its descendants. The phrase "a box's containing block" means "the containing block in which the box lives," not the one it generates.
Each box is given a position with respect to its containing block, but it is not confined by this containing block; it may overflow.
The root of the document tree generates a box that serves as the initial containing block for subsequent layout.
The width of the initial containing block may be specified with the 'width' property for the root element. If this property has the value 'auto', the user agent supplies the initial width (e.g., the user agent uses the current width of the viewport).
The height of the initial containing block may be specified with the 'height' property for the root element. If this property has the value 'auto', the containing block height will grow to accommodate the document's content.
つまんで訳すと、
user agentは、ウィンドウとかページの、viewportを使って、htmlの内容を表示させたりする。(この場合はブラウザなんで、ブラウザの表示領域がviewportだと考えていい) このビューポートがリサイズされたりするたびに、スクロールメカニズムを使って中身のレイアウトを替えたりしてよいよ。
(中略)
ドキュメントのルート要素は、それ以降に続くレイアウトを制御するための最初のボックス(Initial containing block)を作成する。
(中略)
Initial containing blockのheightは、ルート要素のheightプロパティにより指定される。もし、この値がautoであれば、ドキュメントのコンテンツの高さ分拡張される。
想像するに、ほとんどのブラウザのいちばんの親要素は、ブラウザの表示領域となる。これだけが、唯一、何もしなくても高さを明示されている要素であり、こいつは、つまり、高さが560pxとか、ウィンドウの高さによって、明示的に決定されている、レイアウトを制御するための根っことなる要素。要素って言うか、実態はDOM上無いけど(Javascriptでいうdocumentみたいなもの?)、あるようなもの。
その中に、最初の要素、htmlがある。このhtml要素の下に、Initial containing blockが作成される。このボックスの要素はルート要素の高さを参照する。つまり、htmlのheightプロパティの値を参照する。
表示領域の高さが560pxだとすると、viewportのheight:560pxは確定で、その中の最初の要素であるhtmlにheight:100%を指定すると、htmlの高さが560px、その下に作成されるInitial containing blockの高さが100%→560pxで確定し、その子であるbodyにheight:100%を指定すると、bodyの高さが560pxで確定。その子である、div#Containerにheight:100%を指定すると、#Containerの高さが560pxで確定。と、高さ決定が連鎖されるのではないか。そして、viewportの高さが変わると、それに応じてこいつらぜんぶが変わるということで成り立っているんではないのかと思うんだけれどどうなんでしょ。自分的理解はここまでです。
なんだか、bodyとかhtmlっていう要素は、ブラウザ上、特殊な扱いを受けてるっぽいんですわ。だって、bodyにbackground:red;って指定したら、ページの内容が1行しかなくたって、後ろ真っ赤になるじゃないですか。これって、あらかじめheight:100%指定されているような動作ですよね?
でも、例えばbodyにheight:300px;border:1px solid purpleって指定してみると、上から300pxのところまでが紫の線で囲まれるんですけど、これにさらにbody{background:red}って指定したら、300pxのところまでじゃなくて、ブラウザの表示領域全体が真っ赤になる。これって他のブロック要素とは明らかに違う扱いうけてるでしょう。height:300pxなんだからそこまで赤くなるはずじゃ?
それに、div#Containerにheight:100%ってやったら、表示領域一杯じゃなくて、body分なんだから、スクロールしてヘッダーからフッターまで全部含んだ分をbodyの高さとして捕らえるんじゃないの?ていうか普通そう考えるんでないの?それか、表示領域から外れたぶんは、bodyの中身として捕らえられていなくて、そいつらは、普通にスクロールしてページが長く見えるけど、もはやbodyの領域外に飛び出ている、オーバーフローしているものなわけ?しかしbodyの背景色だけは例外で続いている?
さらに、ここらへんの要素の解釈はブラウザによってまちまちな感じらしく、実のところはあまりよくわかりません。
以下はそんなこんなでhtmlとかbodyとかについて色々やってみたけどやっぱりあんまり分かりませんでしたという記事。結論はなんで動作するのか良く分からんということで・・・
himajin100000 2007/6/02 (01:17)
何故かgoo側でトラバ打てなかったのでコメントとして残します。
(テスト用FC2アカウントにも打てなかったので何かの障害かと思っていますが)
http://blog.goo.ne.jp/himajin100000/e/d1fbee643318759c57f46804a43270f4
Takazudo 2007/6/02 (02:48)
ども。トラックバックは、許可してから公開ってことにしてますので問題ないと思いますよ~。今、公開にしました。
anonimo 2007/6/28 (10:40)
>だって、bodyにbackground:red;って指定したら、ページの内容が1行しかなくたって、後ろ真っ赤になるじゃないですか。これって、あらかじめheight:100%指定されているような動作ですよね?
違う。キャンバスに背景が適用されているから。本当はルートであるhtml要素に対して背景指定するのだが、旧来の慣例を重視してbody要素への指定が推奨されている。キャンバスとは、整形構造が出力される空間のこと。
キャンバスは無限空間だが、実際には表示域(viewport)などの有限領域に出力される。文書がレンダリングされるキャンバス領域より表示域が小さい場合には、スクロールバーなどを出して全部を見れるようにする。
ちなみに、HTML要素に対して背景指定すれば、body自身のボックスにも個別に背景を適用できる。
あと漠然とした「動作」という表現を使うべきではない。この場合は「レンダリング」と言うべき。
>さらに、ここらへんの要素の解釈はブラウザによってまちまちな感じらしく、実のところはあまりよくわかりません。
あなたの疑問はCSS2.1仕樣を読めば万事解決する。CSS2.0の説明は実は支離滅裂。
http://www.kanzaki.com/book/css/3-1-6.html#s3-1-6-6
ルート要素に存在する包含ブロックは、キャンバスの原点(0, 0)に固定された表示域のサイズに基づく矩形領域になる。これを初期包含ブロック(initial containing block)と呼ぶ。
(要するにスクロールされていない状態での“表示域のサイズ”を基準にするということ。)
つまり html { height: 100% } という規則は、初期状態での“表示域の高さ”を参照する。
最近のウェブブラウザなら、大体はそのように実装されている筈。
--
というか無駄な考察に時間を割く余裕があるなら、仕様書しっかり読むなり、ググってください。
Takazudo 2007/6/28 (10:47)
こんにちは、anonimoさん。
Takazudoです。
細かい指摘をありがとうございます。
正直、自分はviewportやcontaining blockについて、正しい理解を得ていませんでした。このエントリは、仕様書を斜め読みしながらわかんねーと思って書いたので、最後の項はあっていると思っていませんし、よくわかっていませんでした。
上に書いてくれたbackgroundのことも、backgroundの項を見たら見つけられました。ありがとうございます。
それと、自分は、CSS2のほうを参照していることが多かったので、今後はCSS2.1を中心に参照するようにします。
kettuxe 2007/10/13 (07:12)
初めまして。
突然ですが、教えてください。
タイトルのところに画像を挿入したところ、全体に下が左へずれてしまいました。センターへもっていきたいのです。
div#container {
width: 760px;
margin-left: auto;
margin-right: auto;
text-align: left;
↑ココの部分がポイントなのでしょうか?
それと、タイトルを消しているため、一番上に「ケッツェライフ」と表示されず、
http://kettuxe.blog122.fc2.com/-Microsoft Internet Explorerとなっています。
ここは変更可能な部分なのでしょうか?(汗
どうぞよろしくお願いいたします(><)
Takazudo 2007/10/16 (01:09)
はじめまして、kettuxeさん。
IE6 中央寄せ margin auto でググってみてください。
きっとみつかります。
陥りやすいバグです。