ボックスは
という三つの配置体系(positioning scheme)によって、どのように配置されるかが決まります。以下では三つの配置体系と、配置されたボックスの位置を相対的に動かす相対位置決め、ボックスの重なりについて説明します。
ボックスの配置を決めるのがpositionプロパティです。
staticrelativeabsolutefixedpositionプロパティの値が"static"以外の要素を位置決めされた(positioned)要素と言います。position:staticの要素は位置決めされていない(non-positioned)要素です。位置決めされたボックスのオフセット量は、topプロパティ、bottomプロパティ、leftプロパティ、rightプロパティによって指定します。
通常フローにあるボックスは、整形文脈に属します。整形文脈にはブロックボックスが属するブロック整形文脈と、インラインボックスが属するインライン整形文脈があります。
初期ブロックボックスはブロック整形文脈(block formatting context)に加わります。ブロック整形文脈の中では、ブロックボックスが上から下に向って縦に積み重なってゆきます。「ブロックレベル要素は前後で改行される」などと一般に説明されているようです。ブロックボックスの左外辺は包含ブロックの左外辺に接するように配置され、ボックス間の上下の間隔はmarginプロパティによって決まります。
フロート、絶対位置決めされた要素、インラインブロック要素、セル要素、表題要素、overflowプロパティが"visible"以外の要素は、新たにブロック整形文脈を設置します。
インラインボックスはインライン整形文脈(inline formatting context)に加わります。インライン整形文脈の中では、インラインボックスは包含ブロックの上から水平方向に向かって並べられます。インラインボックスを包含し行を構成する長方形の領域は行ボックス(line box)と呼ばれます。行ボックスが単一の行に収まりきらないとき、行ボックスは垂直に積み重ねられてゆきます。HTMLの説明で「右端で自動的に折り返される」などと言われているのがこの現象です。垂直方向に重ねられた行ボックスは分離されたり、重なり合ったりすることはありません。行ボックスの幅は通常包含ブロックの幅に一致しますが、間にフロートが入るせいで短縮されることがあります。
<p>このように長い文章は複数の行ボックス
にまたがって表示されます。</p>
![(図)[このように長い文章は複数][の行ボックスにまたがって][表示されます。] ([]が行ボックス)](linebox.png)
インラインボックスが行ボックスの横幅を超えるときは、インラインボックスが分割され複数の行ボックスにまたがって割り当てられます。その際、マージン、ボーダー、パディングの効果は分割された境界面には現れません。
<p>分割された<em>インラインボックス</em>があります。</p>
em { border: 1px solid blue }
![(図)[分割された(インライン][ボックス)があります] ([]が行ボックス、()がインラインボックス)](splitbox.png)
floatプロパティに"left"か"right"が指定された要素の生成するボックスをフロート(float)と言います。フロートは一般に「回り込み」と説明されますが、大雑把には次のような仕様になっています(float:leftの場合、float:rightなら左右逆)。
display:table)のボックスのマージンは、同ブロック内にあるどのフロートとも重なってはいけない。(必要なら、それらの要素をフロートの下に押し下げる。)フロートはブロックボックスとなり、新たなブロック整形文脈を形成します。フロートの中は通常フロー配置となります。
float:noneの場合はフロートになりません。
<p>
<span>floating box</span>
最初の段落です。フロートの幅の分だけ
行ボックスが短くなっているのが分かる
と思います。
</p>
<p>
ここが次の段落です。この段落でも行ボックスの
短縮が起こります。
</p>
span {
float: left;
width: 5em; height: 10em;
border: 1px solid blue }
p { border: 1px solid red }

注目したい点は、フロートがない場合でもp要素のボックスが図と同じように配置されることです。一つめのボックスがフロートを含めるように長くなったり、次のボックスがフロートと重ならないよう下に下がったりはしません。フロートは通常フローからは取り除かれているからです。
<p>
フロートの前の内容です。
<span>floating box</span>
フロートの後の内容です。
</p>
span {
float: left;
width: 5em; height: 5em;
border: 1px solid blue }
p { border: 1px solid red }

上記のルール7により、フロートの直前の行の内容がフロートの右に流し込まれています。
<p>
<span>floating box</span>
Supercalifragilisticexpialidocious
</p>
span {
float: left;
width: 5em; height: 5em;
border: solid 1px blue }
p {
width: 10em;
border: solid 1px red
}

「Supercalifragilisticexpialidocious」はフロートの右に流し込むには行ボックスが短すぎます。そのため、上記のルール8によりフロートの下へ移動します。
<p>
<span>floating box1</span>
<span>floating box2</span>
フロートの後の内容です。
</p>
span {
float: left;
width: 5em; height: 5em;
border: 1px solid blue }
p { border: 1px solid red }

左フロートが連続する場合、後続するフロートは先行するフロートの左外辺に接するまで移動します。(ルール1)
<p>
<span>floating box1</span>
<span>floating box2</span>
フロートの後の内容です。
</p>
span {
float: left;
width: 5em; height: 5em;
border: 1px solid blue }
p {
width: 9em;
border: 1px solid red
}

上とほぼ同じコードですが、p要素をwidth:9emとしたため、フロートを二つ横に並べることができなくなりました。そのため、ルール3により後続するフロートが先行するフロートの下に押し下げられています。
フロートにはさらに厳密なルールが定められています(float:leftの場合、float:rightなら左右逆)。便宜上、これを厳密ルールと呼ぶことにします。
clearプロパティが宣言されたフロートの上外辺は、clear:leftの場合は先行する全ての左フロートの下外辺よりも下、clear:rightの場合は右フロートの下外辺よりも下、clear:bothの場合はどちらのフロートの下外辺よりも下でなければならない。フロートを利用して段組を組むときは、この厳密なルールをよく理解しておくことが必要になります。
<div id="container">
<div id="boxA">boxA</div>
<div id="boxB">boxB</div>
<div id="boxC">boxC</div>
</div>
div#container {
width: 300px;
overflow: auto;
border: 2px solid black
}
div#boxA {
float: left;
width: 50px;
background: #ffcfce
}
div#boxB {
float: left;
width: 150px; background: #cecfff
}
div#boxC {
float: left;
width: 100px;
background: #ceffce
}
boxA、boxB、boxCの包含ブロックの幅は300pxであり、各ボックスを横に並べるとちょうど収まります。このような場合、厳密ルール1によりboxAの左外辺が包含ブロックの左辺に重なり、厳密ルール2、8、9によりboxBとboxCが横に並べられます。boxA、boxB、boxCの上外辺は厳密ルール8、4、5により包含ブロックの上辺に一致します。

<div id="container">
<div id="boxA">boxA</div>
<div id="boxB">boxB</div>
<div id="boxC">boxC</div>
</div>
div#container {
width: 250px;
overflow: auto;
border: 2px solid black
}
div#boxA {
float: left;
width: 50px;
background: #ffcfce
}
div#boxB {
float: left;
width: 150px; background: #cecfff
}
div#boxC {
float: left;
width: 100px;
background: #ceffce
}
包含ブロックの幅は250pxであり、boxA、boxBは横に並べられますが、boxCを横に並べると右にはみ出してしまいます。このような場合は厳密ルール7、8、9によりboxCがboxAの下に配置されます。

CSS 2ではフロートは何らかの方法で幅が明示されていなければならないという規定がありましたが、CSS 2.1でこの規定は削除されました。フロートがwidth:autoのとき、フロートは「内容に合わせて縮めた幅」を持つとされています。
フロートのクリアにはclearプロパティを使います。これもまた「回り込みの解除」とよく説明されるのですが、正確にはそうではありません。
clear:leftが指定された要素のボックスの上外辺は、ソース文書中で前にある要素が生成する左フロートの下外辺より下に位置する。(clear:rightの場合は右フロートの下外辺よりも下。)clear:bothが指定された要素のボックスの上外辺は、ソース文書中で前にある要素が生成するどのフロートの下外辺よりも下に位置する。clearプロパティが適用されるのはブロックレベル要素のみです。
clearプロパティが指定された要素のボックスは、margin-topプロパティによる上マージンの量がそのボックスをフロートより下に位置させるには不十分なとき、クリアランス(clearance)と呼ばれる空白が必要な量だけ上マージンの上に加えられます。
<p id="boxA">
<span>floating box</span>
最初の段落です。フロートの幅の分だけ
行ボックスが短くなっているのが分かる
と思います。
</p>
<p id="boxB">
ここが次の段落です。
</p>
span {
float: left;
width: 5em; height: 10em;
border: 1px solid blue }
p#boxB {
clear: left;
margin-top: 6em
}
p { border: 1px solid red }
boxBにclear:leftが指定されていますが、boxBがフロートより下に位置するには上マージンだけで十分なので、クリアランスは挿入されません。

span {
float: left;
width: 5em; height: 10em;
border: 1px solid blue }
p#boxB {
clear: left;
margin-top: 3em
}
p { border: 1px solid red }
margin-top:3emだけではboxBがフロートの下にならないため、クリアランスが挿入されます。

clearプロパティは、それが指定された要素の中にあるフロートや、別のブロック整形文脈にあるフロートとは関係しません。
<div id="boxA">boxA</div>
<div id="boxB">
boxB
<div id="clear">clear:left</div>
boxB
</div>
div#boxA {
float: left;
width: 100px;
height: 100px;
border: 1px solid red
}
div#boxB {
float: left;
width: 100px;
height: 200px;
border: 1px solid blue
}
div#clear {
clear: left;
background-color: #afa;
border: 1px solid green
}
boxAとboxBを左フロートにすることで、横に並べています。左フロートであるboxBは新たにブロック整形文脈を設置するため、その中にあるclear:leftが指定されたボックスが別のブロック整形文脈にあるboxAより下に位置することはありません。

div#boxA {
float: left;
width: 100px;
height: 100px;
border: 1px solid red
}
div#boxB {
margin-left: 102px;
width: 100px;
height: 200px;
border: 1px solid blue
}
div#clear {
clear: left;
background-color: #afa;
border: 1px solid green
}
boxBに左マージンを取ることで、boxAとboxBを横並びにしています。このとき、boxBは新たなブロック整形文脈を設置しません。よって、boxAとclear:leftが指定されたボックスは同じブロック整形文脈にあります。したがって、clear:leftが指定されたボックスの上辺が左フロートであるboxAの下辺より下になるようクリアランスが設けられます。

「clearプロパティを使ったら謎の空白ができた」というような場合、この例のようになっている可能性が高いでしょう。
positionプロパティが"absolute"か"fixed"である要素を絶対位置決めされた要素(absolutely positioned element)と言います。絶対位置決めには
position:absolute)position:fixed)の二つがあります。絶対位置決めされた要素は通常フローから完全に取り除かれます。
position:absoluteが指定された要素のボックスは、包含ブロックからtopプロパティかbottomプロパティ、leftプロパティかrightプロパティで指定されたオフセット量の分だけ移動した位置に配置されます。
position:absoluteが指定された要素の包含ブロックは、直近の祖先要素で位置決めされた(positionプロパティが"static"以外)ボックスのパディング辺です。そのようなボックスがなければ、初期包含ブロックが包含ブロックとなります。
<body>
<div>
ここがdiv要素の中
<span>position:absolute</span>
</div>
</body>
span {
position: absolute;
top: 0;
right: 0;
border: 1px solid red
}
div { border: 1px solid blue }
body { padding: 10px }
位置決めされたボックスがないため、絶対配置されたspan要素の包含ブロックは初期包含ブロックとなります。

span {
position: absolute;
top: 0;
right: 0;
border: 1px solid red
}
div {
position: relative;
border: 1px solid blue
}
body { padding: 10px }
div要素が位置決めされているため、絶対配置されたspan要素の包含ブロックはdiv要素の生成するボックスのパディング辺となります。

position:fixedが指定された要素のボックスも、包含ブロックからtopプロパティかbottomプロパティ、leftプロパティかrightプロパティで指定されたオフセット量の分だけ移動した位置に配置されます。
position:fixedが指定された要素の包含ブロックは、「連続」グループのメディアであれば表示域サイズの長方形、「ページ」グループのメディアであればページボックスです。つまり、ブラウザであればウィンドウをスクロールしても表示域は移動しないためボックスは固定して表示され、プリンタで印刷するのであれば各ページの同じ位置にボックスが出力されます。
通常フローで配置されたボックスやフロートは、position:relativeを指定すると相対的に位置を変化させることができます。これを相対位置決め(relative positioning)と言います。相対位置決めは他のボックスの配置には全く影響を与えず、相対位置決めされていない他のボックスは相対位置決めされたボックスがそうされていない場合と同じ場所に位置します。
オフセット量はtopプロパティ、bottomプロパティ、leftプロパティ、rightプロパティで指定します。算出値は次のように導出します。
left:auto; right:autoなら0leftプロパティ、rightプロパティのどちらかが"auto"の場合、"auto"でないプロパティの値leftプロパティ、rightプロパティがどちらも"auto"でない場合、direction:ltrならleftプロパティの値、direction:rtlならrightプロパティの値top:auto; bottom:autoなら0topプロパティ、bottomプロパティのどちらかが"auto"の場合、"auto"でないプロパティの値topプロパティ、bottomプロパティがどちらも"auto"でない場合、topプロパティの値<div>
span要素の前
<span>position:relative</span>
span要素の後
</div>
span {
position: relative;
top: 2em;
right: 5em;
border: 1px solid red
}
div {
position: relative;
border: 1px solid blue
}
span要素を相対位置決めしています。span要素の前後の匿名インラインボックスは、span要素のボックスが移動する前と同じ位置に配置されます。

ボックスは水平・垂直方向に加えてz軸方向の位置を持ちます。絶対位置決め、相対位置決めなどによってボックスどうしが重なるときは、z軸において上にあるボックスが前面に描画されます。
それぞれのボックスはスタック文脈(stacking context)に属しています。スタック文脈中のボックスは、同じスタック文脈の中にある他のボックスとのz軸上の位置関係を示すスタックレベル(stack level)という整数値を持ちます。スタックレベルの高いボックスほど前面に描画されます。スタックレベルが同じであるボックスは、文書ツリー上の順番にしたがって後ろから前へ積み重ねられます。
z-indexプロパティはボックスの重なりを指定するプロパティです。このプロパティは位置決めされた(positionプロパティが"static"以外の)要素に適用されます。値には<整数値>か"auto"を指定します。<整数値>は現在のスタック文脈中におけるスタックレベルを表し、さらに自身のスタックレベルが"0"である局所スタック文脈(local stacking context)を設置します。つまり、スタック文脈が別のスタック文脈を包含するということです。値が"auto"であれば、現在のスタック文脈におけるスタックレベルは親要素のボックスと同じになり、新たな局所スタック文脈は設置しません。また、ルート要素はルールスタック文脈を設置します。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Layer test</title>
</head>
<body>
<div id="stack1">
stack1(z-index:1)
<div id="stack1-1">
stack1-1(z-index:3)
</div>
</div>
<div id="stack2">
stack2(z-index:2)
<div id="stack2-1">
stack2-1(z-index:1)
</div>
</div>
</body>
</html>
div#stack1 {
z-index: 1;
width: 200px;
height: 200px;
position: absolute;
top: 0; left: 0;
background-color: #afa
}
div#stack1-1 {
z-index: 3;
width: 100px;
height: 100px;
position: absolute;
top: 70px; left: 130px;
background-color: #99f
}
div#stack2 {
z-index: 2;
width: 200px;
height: 200px;
position: absolute;
top: 100px; left: 100px;
background-color: #faa
}
div#stack2-1 {
z-index: 1;
width: 100px;
height: 100px;
position: absolute;
top: 50px; left: -50px;
background-color: #fff777
}
上の例は以下のように表示されます。

まず、ルート要素(html要素)がルートスタック文脈を設置します。その文脈の中で、stack1のスタックレベルは1、stack2のスタックレベルは2となり、stack2がstack1より前面になります。stack2は別のスタック文脈を設置します。その文脈にあるのはstack2とstack2-1で、スタックレベルはそれぞれ0と1になります。よって、最も前面に表示されるのはstack2-1で、その次がstack2です。stack1も別のスタック文脈を設置します。その中ではstack1のスタックレベルが0、stack1-1のスタックレベルが3です。
z-indexプロパティの値は自身が属するスタック文脈におけるスタックレベルです。ですから、その値が大きければ必ず前面に表示されるというわけではありません。例えば、この例ではz-index:1であるstack2-1の方がz-index:3であるstack1-1よりも前になっています。
| スタック文脈を設置する要素 | ||||||
|---|---|---|---|---|---|---|
| ルート要素 | stack1 | stack2 | stack1-1 | stack2-1 | ||
| 要素のスタックレベル | stack1 | 1 | 0 | |||
| stack2 | 2 | 0 | ||||
| stack1-1 | 3 | 0 | ||||
| stack2-1 | 1 | 0 | ||||
スタック文脈をさらに詳しく見ると、次のようになります。
z-index:autoかz-index:0である位置決めされた子孫要素のスタックレベル仕様書ではAppendix E. Elaborate description of Stacking Contextsにさらに詳しい説明があります。