目次
この章及び次の章では、視覚整形モデル、すなわち視覚系媒体を対象にしたUAが木構造をどう処理するかについて述べる。
視覚整形モデルでは、木構造内の各要素がボックスモデルに従ってゼロ個以上のボックスを生成する。 それらボックスのレイアウトは以下の様な事項に左右される:
この章及び次の章で定めるプロパティは、連続媒体とページ媒体の両方に適用される。 ただし、マージンのプロパティについては、ページ媒体で用いる場合にだけ違う意味になる。 詳細は[13 ページ媒体]を参照のこと。
視覚整形モデルは、整形のあらゆる面について規定している訳ではない。 たとえば文字間隔の算出アルゴリズムについては規定しない。 したがって、適合UAであっても本仕様の対象外となる整形については各々異なった動作をしてよい。
一般に、連続媒体に出力するUAは(ウィンドウあるいはその他画面上の視界として)ユーザに閲覧領域(viewport)を提供する。 UAは閲覧領域のリサイズに伴って文書のレイアウトを変更してもよい(初期包含ブロックの項を参照)。 閲覧領域が文書の初期包含ブロックより小さい場合、UAはスクロールの仕組みを提供すべきである。 1つのキャンバスを複数の閲覧領域に関連付けてはならないが、1つの文書を複数のキャンバスへ同時に描画するのは構わない(すなわち1文書に対して同時に別々の閲覧領域を提供してよい)。
CSS2では、ボックスの位置やサイズの多くを、包含ブロック(containing block)と呼ばれる矩形ボックスの四辺を参照することによって計算する。 一般に、ある要素が生成したボックスは、その子孫ボックスの包含ブロックとして機能する。 このことを、ボックスが子孫のために包含ブロックを「設定する」("establishes")と表現する。 「ボックスの包含ブロック」("a box's containing block")と表現した時、それは「そのボックスが含まれている包含ブロック」("the containing block in which the box lives")を指すのであり、「そのボックスが設定する包含ブロック」("the one it generates")を指すのではない。
各ボックスは包含ブロックからの相対位置を与えられるわけだが、その位置は決して包含ブロックの内部だけに制限されるものではなく、外にはみ出しても構わない。
木構造の根にあたる要素もボックスを生成する。 そのボックスは、以降に続くレイアウトの初期包含ブロック(initial containing block)として機能する。
初期包含ブロックの横幅はルート要素の'width'プロパティで指定するとよい。 このプロパティが値'auto'を取る場合はUAが初期幅を決定する(たとえば、その時点における閲覧領域の幅などを用いる)。
初期包含ブロックの高さはルート要素の'height'プロパティで指定するとよい。 このプロパティが値'auto'を取る場合、初期包含ブロックの高さは文書の内容量に合わせて変化することになる。
初期包含ブロックを位置指定したり浮動させたりはできない。 すなわち、ルート要素に'position'や'float'を設定しても、UAはこれらを無視する。
包含ブロックの寸法を計算する方法についての詳細は次章を参照せよ。
以下の章では、CSS2で生成されるボックスの種類について述べる。 視覚整形モデルでは、ボックスの種類が部分的にボックスの動作に影響する。 ボックスの種類は、後で示す'display'プロパティによって指定する。
ブロック要素(block-level elements)とは、ソース文書のうち、見た目にブロック(段落など)として整形される要素のことである。 'display'の値のうちいくつかは、要素をブロックレベルにする。 'block'、'list-item'、'compact'、'run-in'、'table'などがその例である。 (ただし、'compact'と'run-in'は場合によって生成するボックスの種類が変化する。 各解説を参照のこと)
ブロック要素は、内部にブロックボックス(block box)のみを含む主要ブロックボックス(principal block box)を生成する。 主要ブロックボックスは、子孫ボックスや生成内容が参照するための包含ブロックを設定し、自身もまた何らかの配置体系に属する。 また、主要ブロックボックスはブロックの整形コンテキストに属する。
ブロック要素の中には、主要ボックス以外にも更にボックスを生成するものがある。 リスト項目の要素がマーカー入りのボックスを生成する場合などがこれにあたる。 こういったボックスは主要ボックスの位置を基準に配置される。
次の様な文書で:
<DIV> Some text <P>More text </DIV>
DIV要素とP要素が'display: block'だと仮定すると、DIV要素は内容としてインラインとブロックの両方を持っている様に見える。 ここで、整形の定義付けを容易にするために、「Some text」の周囲に匿名ブロックボックス(anonymous block box)があるものと考える。
上の例に出てきたボックスの図、そのうち1つは匿名である
言い換えると、あるブロックボックス(上の例ではDIV要素)が内部に別のブロックボックス(上の例ではP要素)を含む場合、すべてのインラインボックスを匿名ブロックボックスに取り込むことにより、ブロックボックスの中身を強制的にブロックボックスのみの状態にするのである。
このモデルを以下の例にあてはめてみよう。 以下の規則を:
/* Note: HTML UAs may not respect these rules */
BODY { display: inline }
P { display: block }
このようなHTML文書に適用するとしよう:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HEAD> <TITLE>Anonymous text interrupted by a block</TITLE> </HEAD> <BODY> This is anonymous text before the P. <P>This is the content of P.</P> This is anonymous text after the P. </BODY>
BODY要素には、匿名テキスト(C1)、続いてブロック要素、そしてもう1つ匿名テキスト(C2)が含まれている。 すなわち、この例で生成されるボックスは、まずBODY要素周囲の匿名ブロックボックス、C1周囲の匿名ブロックボックス、P要素のブロックボックス、そしてC2周囲の匿名ブロックボックス、の合計4つになる。
匿名ボックスは、自身が含まれる匿名でないボックスからプロパティ値を継承する。 継承を行わないプロパティは初期値を取る。 たとえば、匿名ボックス親要素をDIV要素とすると、匿名ボックスのフォントはDIV要素から継承されるが、マージンは初期値のゼロを取ることになる。
インライン要素(Inline-level elements)とは、ソース文書のうち新たに内容ブロックを形成しない要素であり、その内容は複数の行に分散して挿入される(たとえば、段落の途中に出てくる強調テキストや行内画像など)。 'display'の値のうちいくつかは、要素をインラインにする。 'inline'、'inline-table'、'compact'、'run-in'などがその例である (ただし、'compact'と'run-in'は場合によって生成するボックスの種類が変化する。 各解説を参照のこと)。 インライン要素はインラインボックス(inline box)を生成する。
インラインボックスは状況に応じて様々な整形コンテキストに属する:
次の文書で:
<P>Some <EM>emphasized</em> text</P>
P要素は、複数のインラインボックスを含むブロックボックスを生成する。 「emphasized」を含むのはインライン要素EMが生成するボックスだが、他のボックス(「Some」と「text」を含むもの)はブロック要素Pが生成している。 この様なボックスは、インライン要素と関連が無いので匿名インラインボックス(anonymous inline boxes)と呼ばれる。
匿名インラインボックスは、親のブロックボックスから継承できるプロパティを継承する。 継承性のないプロパティについては初期値を取る。 上の例だと、匿名インラインボックスは、前景色をPから継承するがその背景は透明になる。
本仕様においては、匿名ボックスの種類が文脈から明白な場合、インラインでもブロックでも単に匿名ボックスと呼ぶことにする。
表を整形する際には、更に多種多様な匿名ボックスが出現する。
コンパクトボックス(compact box)は以下の様に動作する:
コンパクトボックスをマージン領域内に配置する場合は以下の様にする:
コンパクトボックスは、後行するブロックの中にある最初の行ボックスには含まれない(書字方向に応じて行ボックスの左側もしくは右側に置く)のだが、それにも拘らず行ボックスの高さの計算には影響を及ぼす。
行ボックスに対するコンパクトボックスの垂直位置は、'vertical-align'プロパティによって決定する。
コンパクトボックスの水平位置は、常にブロックボックスのマージン領域内に確保される。
1行で整形しきれない要素は、後行するブロックボックスのマージン領域に配置できない。 たとえば、HTMLにおいてコンパクトな要素がBR要素(BR要素のデフォルトスタイルは改行挿入であると仮定)を含んでいれば、その要素は常にブロックボックスとして整形することになる。 マージン領域に複数行のテキストを挿入したい場合は、'float'を利用するのが適当であろう。
以下はコンパクトボックスの例である。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>A compact box example</TITLE>
<STYLE type="text/css">
DT { display: compact }
DD { margin-left: 4em }
</STYLE>
</HEAD>
<BODY>
<DL>
<DT>Short
<DD><P>Description goes here.
<DT>too long for the margin
<DD><P>Description goes here.
</DL>
</BODY>
</HTML>
次の様に整形される:
short Description goes here
too long for the margin
Description goes here
マージン領域におけるコンパクト要素の位置を調整するには'text-align'を使うとよい。 'left'だとそのマージンの左辺に揃え、'right'だと右側にある最も近い辺に揃え、'center'だとマージンの中でセンタリングする。 'justify'という値は無効であり、後行するブロックボックスの'direction'の値に応じて、'left'もしくは'right'として扱う。 すなわち、書字方向が'ltr'なら'left'、'rtl'なら'right'扱いになる。
コンパクトボックスと生成内容の相互作用については[12 生成内容]を参照のこと。
ランインボックス(run-in box)は以下の様に動作する:
ランインボックスは、次例の様にヘッダをはめ込む場合に便利である:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>A run-in box example</TITLE>
<STYLE type="text/css">
H3 { display: run-in }
</STYLE>
</HEAD>
<BODY>
<H3>A run-in heading.</H3>
<P>And a paragraph of text that
follows it.
</BODY>
</HTML>
これは次の様に整形される:
A run-in heading. And a paragraph of text that follows it.
ランイン要素が値を継承する場合、ソースツリー上の親要素から値を継承する。 一見すると親であるかの様に見えるブロック要素から継承するのではない。
ランインボックスと生成内容の相互作用については[12 生成内容]を参照のこと。
| Value: | inline | block | list-item | run-in | compact | marker | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | none | inherit |
|---|---|
| Initial: | inline |
| Applies to: | all elements |
| Inherited: | no |
| Percentages: | N/A |
| Media: | all |
各値は以下の様な意味を持つ:
'none'は不可視のボックスを生成する訳ではなく、まったくボックスを生成しないということに注意せよ。 CSSには、不可視にも拘わらず整形に影響するボックスを生成するための、別の仕組みが用意されている。 詳細は[11.2 可視属性]を参照せよ。
'display'の初期値は'inline'になっているが、UAのデフォルトスタイルシ−トにある規則がこの値を上書きできることに注意せよ。 [A HTML4.0におけるスタイルシートの例]を参照のこと。
以下に'display'の例を示す:
P { display: block }
EM { display: inline }
LI { display: list-item }
IMG { display: none } /* 画像を表示しない */
HTMLの適合UAは'display'プロパティを無視してもよい。 そのことは不適合を意味しない。
CSS2には、ボックスをレイアウトするために3種類の配置体系(positioning scheme)が存在する:
注。 CSS2の配置体系を利用することにより、レイアウト効果のみを意図した見せかけのマーク付け(透明画像など)を排除し、文書のアクセシビリティを向上させることが可能となる。
'position'と'float'は、ボックスの位置を計算するためのアルゴリズムを指定するプロパティである。
| Value: | static | relative | absolute | fixed | inherit |
|---|---|
| Initial: | static |
| Applies to: | all elements, but not to generated content |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
各値は以下の様な意味を持つ:
@media screen {
H1#first { position: fixed }
}
@media print {
H1#first { position: static }
}
'position'が'static'以外の値を取る時、その要素は位置指定されている(positioned)と言う。 位置指定された要素は、位置指定されたボックスを生成する。 位置指定されたボックスは以下の4つのプロパティに従ってレイアウトされる:
| Value: | <length> | <percentage> | auto | inherit |
|---|---|
| Initial: | auto |
| Applies to: | positioned elements |
| Inherited: | no |
| Percentages: | refer to height of containing block |
| Media: | visual |
このプロパティは、ボックスのマージン上辺が包含ブロック上辺からどれだけ下に位置しているかを指定する。
| Value: | <length> | <percentage> | auto | inherit |
|---|---|
| Initial: | auto |
| Applies to: | positioned elements |
| Inherited: | no |
| Percentages: | refer to width of containing block |
| Media: | visual |
このプロパティは、ボックスのマージン右辺が包含ブロック右辺からどれだけ左に位置しているかを指定する。
| Value: | <length> | <percentage> | auto | inherit |
|---|---|
| Initial: | auto |
| Applies to: | positioned elements |
| Inherited: | no |
| Percentages: | refer to height of containing block |
| Media: | visual |
このプロパティは、ボックスのマージン下辺が包含ブロック下辺からどれだけ上に位置しているかを指定する。
| Value: | <length> | <percentage> | auto | inherit |
|---|---|
| Initial: | auto |
| Applies to: | positioned elements |
| Inherited: | no |
| Percentages: | refer to width of containing block |
| Media: | visual |
このプロパティは、ボックスのマージン左辺が包含ブロック左辺からどれだけ右に位置しているかを指定する。
各値は以下の様な意味を持つ:
絶対配置のボックスの場合、そのオフセットは包含ブロックに対してのものである。 一方相対配置の場合、そのボックス自身の通常位置の外辺に対して位置が決まる(つまり、まず通常フローによる基準位置が与えられ、それから位置指定のプロパティによって最終的な位置が決まる)。
通常に流し込まれるボックスは、ブロックもしくはインラインの整形コンテキストに属している(両者へ同時に属すことはない)。 ブロックボックスはブロックの整形コンテキストに属し、インラインボックスはインラインの整形コンテキストに属する。
ブロックの整形コンテキストでは、包含ブロックの最上部から上から下へ次々とボックスをレイアウトする。 2つの兄弟ボックス間の縦の距離はマージンのプロパティによって決まる。 隣接するブロックボックス間の垂直マージンは相殺し合う。
ブロックの整形コンテキストでは、各ボックスの外左辺が包含ブロックの左辺と重なっている(整形の方向が右から左の場合は逆)。 これは、たとえ浮動体が混在する場合でも同様である(浮動体の分だけ内容領域が縮みはするものの)。
ページ媒体での改頁については[13.3.4 改頁]を参照のこと。
インラインの整形コンテキストでは、包含ブロックの最上部から水平方向に次々とボックスをレイアウトする。 これらボックス間に存在するマージン、ボーダー、パディングなどはそのまま保持される。 ボックス同士の縦方向の位置は様々な方法で揃えることができる。 たとえば、ボックス同士の外上辺や外下辺を揃えたり、ボックス同士のベースラインを揃えたりできる。 1行を構成する複数のボックスが含まれている矩形領域を、行ボックス(line box)と呼ぶ。
行ボックスの幅は包含ブロックによって、高さは[10.8 行の高さを計算する]で述べる規則に従って決まる。 行ボックスは、常にその内部にあるすべてのボックスを含むのに十分な高さを持つが、内部にある最も高いボックスと同じ高さになるとは限らない(たとえばボックスをベースラインで揃える場合など)。 中にあるボックスよりそれを含む行ボックスの方が高い場合、そのボックスの行ボックス内における縦方向の位置は'vertical-align'によって決まる。
インラインボックスが多すぎて1つの行ボックスに収まらない場合、複数の行ボックスを縦に積み上げて別々に収める。 したがって、段落は行ボックスを縦に積み重ねたものである。 行ボックスは垂直に仕切られることなく(つまり左右に分割されることなく)積み上げられ、行ボックス同士は決して重ならない。
一般に、行ボックスの左辺とその包含ブロックの左辺は重なっており、右辺についても同様である。 しかし、浮動ボックスが包含ブロックの辺と行ボックスの辺の間に入ることがある。 したがって、同じ整形コンテキストに属する行ボックスは一般には同じ幅(すなわち包含ブロックの幅)を有するのだが、浮動体のせいで使える水平スペースが削減される場合は、異なる幅になることもある。 一方高さについては、同じ整形コンテキストに属する行ボックスであっても一般には異なる高さになる(ある行は高さが大きい画像を含むのに対して、別の行はテキストのみである場合など)。
1行に含まれるインラインボックスの幅の合計が行ボックスの幅より小さくなる場合、それらインラインボックスの行ボックス内における水平位置は'text-align'プロパティによって決まる。 その値が'justify'であれば、UAは各インラインボックスの幅を一様に引き延ばしてよい。
インラインボックスは行ボックスの幅を越えてはならないので、長すぎるインラインボックスは複数のボックスに分割して別々の行ボックスへ収める。 インラインボックスを分割した時、その分割面にはマージン、ボーダー、パディングの視覚効果は現れない。 ボックスの分割が双方向書字の途中で発生する場合、マージン、ボーダー、パディングの整形が完全に定まらないことがある。
インラインボックスは、双方向テキスト処理によって同じ行ボックス内で分割される場合もある。
インラインボックスの構築例を示そう。 (HTMLのブロック要素Pによって生成される)以下の段落には、EM要素とSTRONG要素の間に匿名テキストが散在している。
<P>Several <EM>emphasized words</EM> appear <STRONG>in this</STRONG> sentence, dear.</P>
P要素は5つのインラインボックスを含むブロックボックスを生成する。 そのうち3つは匿名ボックスである:
段落を整形する際、UAは5つのボックスを行ボックスに流し込む。 この例だと、P要素のボックスが、行ボックスの包含ブロックを設定することになる。 包含ブロックの幅が十分に広ければ、すべてのインラインボックスが1行の行ボックスに収まるだろう。
Several emphasized words appear in this sentence, dear.
そうでなければ、インラインボックスは分割されて複数の行ボックスへ収まることになる。 すなわち、段落は次の様に分割されたり:
Several emphasized words appear in this sentence, dear.
この様に分割されたりする:
Several emphasized words appear in this sentence, dear.
後者の場合、EM要素のボックスが2つに分割されている(これらをsplit1、split2と呼ぼう)。 split1の直後とsplit2の直前では、周辺領域やその他のテキスト装飾は何の視覚効果も表さない。
次の様な例を考えてみよう:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>Example of inline flow on several lines</TITLE>
<STYLE type="text/css">
EM {
padding: 2px;
margin: 1em;
border-width: medium;
border-style: dashed;
line-height: 2.4em;
}
</STYLE>
</HEAD>
<BODY>
<P>Several <EM>emphasized words</EM> appear here.</P>
</BODY>
</HTML>
P要素の幅次第で、ボックスは次の様に分割され得る:
1度通常フローに従ってボックスをレイアウトし、その通常位置を基準にしてボックスをシフトする。 これを相対配置(relative positioning)と呼ぶ。 この方法でボックス(B1)を配置しても、B1に続くボックス(B2)は何の影響も受けない。 B2は、B1が位置指定されていないかのように配置され、B1のオフセット後に再配置されることはない。 すなわち、相対配置を用いればボックス同士を重ねられることが判る。
相対配置のボックスは、改行やそれに伴って確保されるスペースも含めて、通常時のサイズを維持する。 相対配置のボックスは、通常に流し込まれる子供要素と位置指定される子孫要素のために、新しく包含ブロックを設定する。
相対配置のボックスは、'position'の値が'relative'である要素に生成される。 そして、そのオフセットは'top'、'bottom'、'left'、'right'という4つのプロパティで指定する。
相対配置ボックスが動的であることを利用すれば、スクリプト環境でアニメーション効果を作り出せる('visibility'プロパティも参照のこと)。 また、相対配置は上付き文字と下付き文字の一般的形式として利用することもできる。 ただし、配置を考慮した行高の自動調節は行われない。 詳細は[10.8 行の高さを計算する]を参照のこと。
相対配置の例については[9.8 通常フロー、浮動体、絶対配置を比較する]を参照のこと。
その行の最も左あるいは右に寄せられるボックスのことを浮動体と言う。 浮動体(あるいは浮動ボックス)の最も興味深い点は、その側面に内容が回り込める(あるいは'clear'プロパティでそれを禁止できる)ことである。 つまり、内容は左浮動ボックスの右側、あるいは右浮動ボックスの左側に流し込まれていくのである。 ここからは、浮動体の配置とそれに続く内容の流し込みについての概論である。 浮動体についての正確な規則は'float'プロパティの解説を参照のこと。
浮動ボックスは幅を明確にしなければならない('width'プロパティで割り当てるか、あるいは置換要素の場合はその内在幅を用いる)。 浮動ボックスは左あるいは右に寄せられていき、その外辺が包含ブロックの辺もしくは別の浮動ボックスの外辺に重なると、ブロックボックスになる。 浮動ボックスの上辺は現在の行ボックスの上辺に揃える(行ボックスが無ければ先行するブロックボックスの下辺に揃える)。 現在の行に浮動体を収めるだけの高さが無ければ、浮動体は行に収まるようになるまで次々に下の行へ侵入する。
浮動体は通常フローに属していないので、その前後に生成される位置指定されていないブロックボックスは、浮動体が存在しないかのように流し込まれる。 しかし、浮動体に続いて生成される行ボックスについては、浮動体の位置を確保するために幅が短縮される。 浮動ボックス直前の行に含まれる内容は、浮動体の側面に現れる最初の行へ新たに流し込みなおす。
複数の浮動体が隣接する場合、それらの浮動体には同じ行を割り当てる。
次の規則は、class="icon"であるすべてのIMGボックスを左に浮動させる(そして左マージンをゼロに設定する):
IMG.icon {
float: left;
margin-left: 0;
}
次のHTMLソースとスタイルシートを考えてみよう:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>Float example</TITLE>
<STYLE type="text/css">
IMG { float: left }
BODY, P, IMG { margin: 2em }
</STYLE>
</HEAD>
<BODY>
<P><IMG src=img.gif alt="This image will illustrate floats">
Some sample text that has no other...
</BODY>
</HTML>
IMGのボックスは左に浮動する。 その後に続く内容は、浮動体右側の同じ行から整形され始める。 浮動体の右側の行ボックスは、浮動体の出現によって幅が短くなるが、浮動体より後ろでは通常の幅(P要素に設定された包含ブロックの幅)に戻る。 よって、この文書は次の様に整形される:
文書が次の様になっても整形は同じである:
<BODY>
<P>Some sample text
<IMG src=img.gif alt="This image will illustrate floats">
that has no other...
</BODY>
何故なら、浮動体直前の内容は元の場所を取り消されて、浮動体の右側へ新たに流し込みなおされるからである。
浮動ボックスのマージンが、隣接するボックスのマージンと相殺し合うことは決してない。 したがって前の例において、P要素のボックスと、IMG要素の浮動ボックスの間でマージンが相殺されることはない。
浮動ボックスは、通常に流し込まれる他のボックスに重ねることができる(たとえば浮動体に続く通常ボックスが負のマージンを持つ場合など)。 インラインボックスが浮動体と重なる場合、そのインラインボックスの内容、背景、及びボーダーは浮動体の前面に表示される。 ブロックボックスが浮動体と重なる場合、そのブロックボックスの背景及びボーダーは浮動体の背面に隠され、(浮動)ボックスが透過している箇所のみが見える。 ブロックボックスの内容は、浮動体の前面にレンダリングされる。
以下の図は、浮動体が通常フローにある要素のボーダーと重なった状態である。
浮動画像がブロックボックスのボーダーを覆い隠す
次の例では、浮動体側面への内容の流し込みを禁止する'clear'プロパティを使っている。
このような規則があれば:
P { clear: left }
次の様に整形される:
このプロパティは、ボックスを右か左に浮動させるか、あるいは全く浮動させないかを指定する。 このプロパティは絶対配置でないボックスを生成する要素に設定できる。 各値は以下の様な意味を持つ:
以下は浮動体の働きを規定する厳密な規則である:
このプロパティは、その要素が生成するボックスのどちら側が、先行する浮動ボックスと隣接してはならないかを指定する。 (その要素自身が浮動子孫要素を有するという場合もあるが、'clear'はそれらの浮動ボックスには無効である)
このプロパティはブロック要素(浮動要素も含む)にのみ指定してよい。 コンパクト及びランインボックスに指定した場合、それらが最終的にブロックボックス扱いならば有効になる。
浮動しないブロックボックスに適用される時、各値は以下の様な意味を持つ:
このプロパティが浮動要素に設定された場合、浮動体の配置についての規則が修正されることになる。 すなわち更に10番目の制約が加わるのである:
絶対配置のボックスは、包含ブロックに対する位置を明示され、通常フローから完全に取り除かれる(つまり兄弟要素に全く影響しない)。 絶対配置のボックスは、通常に流し込まれる子供と位置指定される子孫のために、新しく包含ブロックを設定する。 しかし、絶対配置要素の内容は他のどのボックスにも流し込まれない。 絶対配置のボックスが、重なるボックスの前面にくるか背面にくるかは、スタックレベルによって決まる。
本仕様で絶対配置の要素(absolutely positioned element)と言う時は、その要素の'position'プロパティが'absolute'か'fixed'であることを意味する。
固定配置は絶対配置の1種である。 固定配置ボックスの包含ブロックは閲覧領域に設定するというのが、唯一の相違点である。 連続媒体では、文書がスクロールしても固定配置ボックスは動かない。 この点で、固定配置ボックスは固定背景画像によく似ている。 ページ媒体では、固定配置ボックスは各ページに繰り返される。 このことは、たとえば各ページの下部に署名を付けたい場合などに有用である。
固定配置ボックスは、フレームのような体裁を創り出すのに使用できる。 次のフレームレイアウトを考えてみよう:
このレイアウトは、次のHTML文書とスタイル規則で実現することになる:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>A frame document with CSS2</TITLE>
<STYLE type="text/css">
BODY { height: 8.5in } /* Required for percentage heights below */
#header {
position: fixed;
width: 100%;
height: 15%;
top: 0;
right: 0;
bottom: auto;
left: 0;
}
#sidebar {
position: fixed;
width: 10em;
height: auto;
top: 15%;
right: auto;
bottom: 100px;
left: 0;
}
#main {
position: fixed;
width: auto;
height: auto;
top: 15%;
right: 0;
bottom: 100px;
left: 10em;
}
#footer {
position: fixed;
width: 100%;
height: 100px;
top: auto;
right: 0;
bottom: 0;
left: 0;
}
</STYLE>
</HEAD>
<BODY>
<DIV id="header"> ... </DIV>
<DIV id="sidebar"> ... </DIV>
<DIV id="main"> ... </DIV>
<DIV id="footer"> ... </DIV>
</BODY>
</HTML>
ボックスの生成とレイアウトに関する3つのプロパティ('display'、'position'、'float')は次の様に相互作用し合う:
注。 CSS2では、これらのプロパティ値がスクリプトによって変更させられた時の、レイアウトの動きを特定しない。 たとえば、'width: auto'である要素を位置指定しなおすとどうなるのだろうか?。 内容を再び流し込むのだろうか、それとも元の整形を維持するのだろうか?。 これらは本仕様の対象外の問題であり、UAの挙動はCSS2の初期実装方法によって異なる。
通常フロー、相対配置、浮動体、そして絶対配置を比較するために、以下のHTML断片に基づいていくつか例を挙げる。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>Comparison of positioning schemes</TITLE>
</HEAD>
<BODY>
<P>Beginning of body contents.
<SPAN id="outer"> Start of outer contents.
<SPAN id="inner"> Inner contents.</SPAN>
End of outer contents.</SPAN>
End of body contents.
</P>
</BODY>
</HTML>
この文書に次の規則を適用するとする:
BODY { display: block; line-height: 200%;
width: 400px; height: 400px }
P { display: block }
SPAN { display: inline }
一意属性がouterとinnerである要素(以下単にouter、innerと記す)に生成されるボックスの最終的な配置は、それぞれの例によって異なる。 それぞれの図において、図の左端に振った番号は通常フローの行番号である(見やすさのために行間は広く取った)。 図の縦横比が実際とは異なることに注意せよ。
outerとinnerに次のCSS宣言を設定すると考えてみよう。 これらの宣言は通常フローを変更しない:
#outer { color: red }
#inner { color: blue }
P要素はインラインであるすべての内容、つまり匿名インラインテキストと2つのSPAN要素を含んでいる。 したがってそれらの内容は、P要素が設定した包含ブロック内で、インラインの整形コンテキストに従ってレイアウトされることになる。 つまり次の様になる:
相対配置の体裁を理解するために次の指定を行ってみる:
#outer { position: relative; top: -12px; color: red }
#inner { position: relative; top: 12px; color: blue }
テキストはouterの直前まで通常に流し込まれる。 outerも1度は通常通りの位置とサイズで、1行目の末尾に流し込まれる。 その状態から、3行に亘る(3つの)インラインボックスが、ひとまとまりとして'12px'分上にシフトされる。
innerの内容は、outerの子供要素として「of outer contents」の直後に通常に流し込まれる。 しかし、その後でouterの内容に対して'12px'分下にシフトされるので、結局元の位置に戻ることになる。
outerの後に続く内容は、outerを相対配置しても何の影響も受けないことに注意せよ。
outerの位置指定が'-24px'なら、outerと本体のテキストが重なることになる。
次の規則を用いて、inner要素を右に浮動させることを考えてみよう:
#outer { color: red }
#inner { float: right; width: 130px; color: blue }
テキストはinnerボックスの直前まで通常に流し込まれる。 しかし、innerボックスは通常フローから引っ張り出されて(Pボックスの)右マージンへと浮動する('width'の値が明示されているから)。 浮動ボックスの左側にくる行ボックスは幅を短縮され、残りのテキストがそこに流し込まれる。
'clear'プロパティの効果を示すため、例の文書に兄弟要素を付け加えてみよう:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>Comparison of positioning schemes II</TITLE>
</HEAD>
<BODY>
<P>Beginning of body contents.
<SPAN id=outer> Start of outer contents.
<SPAN id=inner> Inner contents.</SPAN>
<SPAN id=sibling> Sibling contents.</SPAN>
End of outer contents.</SPAN>
End of body contents.
</P>
</BODY>
</HTML>
これに次の規則を適用すると:
#inner { float: right; width: 130px; color: blue }
#sibling { color: red }
innerボックスは前例と同様に右へ浮動し、残りのテキストはあいた空間に流し込まれる:
しかし、付け加えた兄弟要素の'clear'プロパティを'right'に設定すると(つまり、その兄弟要素が生成するボックスの右側に浮動ボックスが隣接するのを禁止すると)、その兄弟要素の内容は浮動体の下から流し込まれる。
#inner { float: right; width: 130px; color: blue }
#sibling { clear: right; color: red }
最後に絶対配置の体裁について考えてみよう。 outerとinnerに次のCSS宣言を適用すると:
#outer {
position: absolute;
top: 200px; left: 200px;
width: 200px;
color: red;
}
#inner { color: blue }
outerボックスの(内容)上辺の位置は、包含ブロックに対して決まる。 また、位置指定されたボックスの包含ブロックは、同じく位置指定されている最も近い祖先に設定される(あるいはそのような祖先が存在しなければ、この例のように初期包含ブロックを用いる)。 outerボックスの上辺は包含ブロックの上辺から'200px'下に位置し、同様にouterボックスの左辺は包含ブロックの左辺から'200px'右に位置する。 そして、outerの子供ボックスは親に対して通常に流し込まれる。
以下は、絶対配置ボックスが相対配置ボックスの子供になる例である。 親であるouterは実際のところ位置指定されていないが、'position'の値が'relative'なので、そのボックスは位置指定される子孫の包含ブロックとして働くことになる。 outerは複数行に分割されたインラインボックスなので、1つめのインラインボックスの上辺と左辺(下の図に太い破線で示した箇所)が、'top'と'left'による位置決めに際して参照される。
#outer {
position: relative;
color: red
}
#inner {
position: absolute;
top: 200px; left: -100px;
height: 130px; width: 130px;
color: blue;
}
これは次の様な配置になる:
outerボックスが位置指定されていなければ:
#outer { color: red }
#inner {
position: absolute;
top: 200px; left: -100px;
height: 130px; width: 130px;
color: blue;
}
innerの包含ブロックには初期包含ブロックが用いられる。 次の図は、この場合のinnerボックスの位置を示している。
相対配置と絶対配置を使うと、次例の様に上下に動く棒を実装できる。 次の文書は:
<P style="position: relative; margin-right: 10px; left: 10px;"> I used two red hyphens to serve as a change bar. They will "float" to the left of the line containing THIS <SPAN style="position: absolute; top: auto; left: -1em; color: red;">--</SPAN> word.</P>
この様になる:
まず、もっとも上位の段落が通常に流し込まれる(包含ブロックの辺を図の両端に示した)。 それから、段落の左辺を包含ブロックの左辺から右に'10px'シフトする(最後の位置を見越して'10px'の右マージンを予約してある)。 動く棒として働く2つのハイフンは流れから取り除かれて、現在の行で('top: auto'だから)、包含ブロック(P要素の最終的な位置によって決まる)の左辺から'-1em'右にシフトされる。 その結果、動く棒が現在の行の左に浮いているかのようになる。
この章で「より前面に」("in front of")という表現は、ユーザが画面と向かい合っている時に、よりユーザに近いことを意味する。
CSS2では各ボックスが三次元空間に位置を持つ。 ボックスの水平位置と垂直位置に加えて「Z軸」が存在し、あるボックスは別のボックスより前面に整形される。 特に、ボックス同士が見た目に重なる時にZ軸は意味を帯びる。 この章では、ボックスがZ軸に沿ってどう配置されるかを述べる。 【訳注:「スタックコンテキスト」を連発すると読み難いので、以下「スタック」を適当に省略する】
各ボックスはいずれかのスタックコンテキスト(stacking context)に属している。 ボックスは、そのコンテキストにおけるスタックレベル(stack level)という整数値を有する。 このスタックレベルが、同じコンテキスト内の他のボックスに対する、Z軸上の相対的な位置を示している。 スタックレベルが大きいボックスは、スタックレベルが小さいボックスより常に前面に整形される。 負のスタックレベルも指定してよい。 同じコンテキストに同じスタックレベルを持つボックスがある場合、木構造内での順番に従って背面から前面へとボックスを積み重ねていく。
ルート要素は、ルートスタックコンテキスト(root stacking context)なるものを設定する。 一方ルート以外の要素は、局所スタックコンテキスト(local stacking contexts)を設定してよい。 コンテキストは継承される。 局所コンテキストは各階層における構造の基本単位(atomic)であるから、あるボックスが同時に複数のコンテキストへ属すことはできない。
局所コンテキストを設定する要素は、2種類のスタックレベルを持つボックスを生成する。 一方は自身が設定したコンテキストにおけるスタックレベル(これは常に'0')、他方は実際に属しているコンテキストにおけるスタックレベル(これは'z-index'プロパティで与えられる)である。
ボックスに対して'z-index'でスタックレベルを明示しないと、親ボックスのスタックレベルを継承する。
位置指定されたボックスに対して、'z-index'プロパティは以下の事項を指定する:
各値は以下の様な意味を持つ:
次の例において、(id属性で識別される)各ボックスのスタックレベルは:
"text2"=0, "image"=1, "text3"=2, "text1"=3
となっている。
text2のスタックレベルはルート要素からの継承である。
その他のスタックレベルは'z-index'プロパティで指定されている。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>Z-order positioning</TITLE>
<STYLE type="text/css">
.pile {
position: absolute;
left: 2in;
top: 2in;
width: 3in;
height: 3in;
}
</STYLE>
</HEAD>
<BODY>
<P>
<IMG id="image" class="pile"
src="butterfly.gif" alt="A butterfly image"
style="z-index: 1">
<DIV id="text1" class="pile"
style="z-index: 3">
This text will overlay the butterfly image.
</DIV>
<DIV id="text2">
This text will be beneath everything.
</DIV>
<DIV id="text3" class="pile"
style="z-index: 2">
This text will underlay text1, but overlay the butterfly image
</DIV>
</BODY>
</HTML>
この例で示したのは透過の考え方である。 デフォルトでは、ボックスの内容のうち透明の領域を通して、背面にあるボックスが見えるようになっている。 この例では、各ボックスは透けた状態で下にあるボックスに被さる。 背景のプロパティを用いると、この効果を上書きできる。
ある種の言語では、文字を右から左に記述する。 特にアラビア語やヘブライ語を書く場合や、複数の言語が混在する文章を書く場合は、あるひとまとまりのテキストに別の書字方向が混在することもある。 この現象を双方向書字(bidirectionality)と呼ぶ。
[UNICODE]の標準規格では、適切な書字方向を決定するための複雑なアルゴリズムを規定している。 そのアルゴリズムには、書字方向情報の埋め込みや上書きによる明示的な制御だけでなく、文字自身に内在する特性に基づいた、暗示的な制御も含まれている。 CSS2では、双方向書字の適切なレンダリングを行うためにこのアルゴリズムを利用する。 'direction'及び'unicode-bidi'プロパティを用いると、構造化言語の要素や属性と、このアルゴリズムの対応関係を指定できる。
文書が右から左へ書かれる文字を含み、UAがこれらの文字を(疑問符や16進コード、黒四角などの任意の代替物ではなく適切なグリフを用いて)表示できる時、UAは双方向書字のアルゴリズムを適用しなければならない。 アラビア語やヘブライ語で書かれた文書で必ずしも書字方向が混在している訳ではないが、これらの文書がそうなる(たとえば数字や他言語のテキストを含む)確率は、左から右に書かれる言語の文書が同じことになる確率よりもはるかに高い。 段落冒頭の必要条件が一見片務的なのは、この事実を反映したからである。
テキストの書字方向は構造化言語の構造と意味に深く関わっているので、多くの場合、これらのプロパティはDTDの設計者や特殊な文書の著者のみが用いるべきである。 デフォルトスタイルシートがこれらのプロパティを指定している場合、文書作成者やユーザはそれを上書きするような規則を指定すべきではない。 しかし、ユーザの要求によって(通常ヘブライ文字で書かれる)イディッシュをラテン文字に音訳する場合などは、典型的な例外としてUAの双方向書字機構を上書きするとよいだろう。
[HTML40]仕様の8.2章では、HTML要素における双方向書字の仕組みを規定している。 したがって、HTMLの適合UAは、文書作成者とユーザのスタイルシートにある'direction'及び'unicode-bidi'プロパティを無視してもよい。 [HTML40]に定めてある双方向書字の仕組みを実現するスタイルシートは、[A HTML4.0でのスタイルシート例]に示してある。 また、HTML4.0の仕様には、双方向書字の問題について更に詳しい情報が含まれている。
| Value: | ltr | rtl | inherit |
|---|---|
| Initial: | ltr |
| Applies to: | all elements, but see prose |
| Inherited: | yes |
| Percentages: | N/A |
| Media: | visual |
このプロパティは、ブロックの基本書字方向と、Unicodeの双方向書字アルゴリズムにおける埋め込み及び上書きの方向('unicode-bidi'を参照)を指定する。 更に、表列のレイアウト方向、内容がはみ出す方向、'text-align: justify'であるブロック内において、不完全な最終行が寄せられる方向、なども指定する。
各値は以下の様な意味を持つ:
'direction'プロパティがインライン要素に何らかの効果を持つには、'unicode-bidi'の値が'embed'か'override'でなければならない。
注。 'direction'プロパティを表の列要素に指定しても、列要素は木構造内に存在しないので、その値は列内のセルに継承されない。 したがってCSSでは、[HTML40]仕様の11.3.2.1に記述があるdir属性の継承を容易に表現することができない。
| Value: | normal | embed | bidi-override | inherit |
|---|---|
| Initial: | normal |
| Applies to: | all elements, but see prose |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
各値は以下の様な意味を持つ:
各ブロック要素の最終的な文字の並びは、双方向書字の制御コードが上の説明の通りに付け加えられ、マーク付けが取り除かれた状態と同じになる。 そして、その文字の並びはプレーンテキストとしてUnicodeの双方向書字アルゴリズムの処理に通され、スタイル指定されたテキストと同じように改行を生じる。 この過程で、画像などの非テキスト実体の扱いは、それらの要素の'unicode-bidi'の値により異なる。 値が'normal'の場合、通常の文字として扱う。 値が'normal'以外の場合、指定された書字方向に従う特殊文字として扱う。
インラインボックスの流し込み方向を統一できるように(完全に左から右か、完全に右から左か)、匿名も含めたより多くのインラインボックスを生成しなければならないこともある。 また、ボックスを流し込む前に、分割してから方向転換をしなければならないこともある。
Unicodeのアルゴリズムは埋め込みレベルの最大値を15に制限しているので、'unicode-bidi'が不適切に'normal'以外の値を取らないよう配慮すべきである。 特に、'inherit'を用いる時は十分警戒すべきである。 ただ、'inherit'の指定を受ける要素は一般にブロックとして表示されるので、インライン単位で書字方向を変更する場合、要素を正しく保つのには'unicode-bidi: embed'という設定をするのがよい(下の例を参照)。
次例は双方向書字のテキストを含むXML文書である。 この例は、DTDの設計者が言語そのもの(要素と属性)と付随するスタイルシートの両方に配慮すべきであるという、重要な設計原則を示している。 つまり、双方向書字に関する規則は他のスタイル規則とは別けて設計すべきであり、構造化言語やDTDの双方向書字指定を保持するためにも、その規則が他のスタイルシートに上書きされるべきではないのである。
この例で、小文字は左から右に並ぶ性質の文字、大文字は右から左に並ぶ性質の文字を表す:
<HEBREW> <PAR>HEBREW1 HEBREW2 english3 HEBREW4 HEBREW5</PAR> <PAR>HEBREW6 <EMPH>HEBREW7</EMPH> HEBREW8</PAR> </HEBREW> <ENGLISH> <PAR>english9 english10 english11 HEBREW12 HEBREW13</PAR> <PAR>english14 english15 english16</PAR> <PAR>english17 <HE-QUO>HEBREW18 english19 HEBREW20</HE-QUO></PAR> </ENGLISH>
これはXMLの例なので、スタイルシートで書字方向を設定する必要がある。 以下がそのスタイルシートである:
/* Rules for bidi */
HEBREW, HE-QUO {direction: rtl; unicode-bidi: embed}
ENGLISH {direction: ltr; unicode-bidi: embed}
/* Rules for presentation */
HEBREW, ENGLISH, PAR {display: block}
EMPH {font-weight: bold}
HEBREW要素は基本書字方向が右から左のブロック、ENGLISH要素は基本書字方向が左から右のブロックである。 PAR要素は基本書字方向を親から継承するブロックである。 したがって、最初2つのPAR要素は右から読まれ、最後3つのPAR要素は左から読まれる。 ここで、HEBREWあるいはENGLISHという要素名は、判り易さを考慮して選んであるにすぎないことに注意せよ。 一般に、要素名は内容の言語とは無関係に、構造を伝達すべきである。
EMPH要素はインラインであり、'unicode-bidi'の値が'normal'なので、書字方向の転換は起こらない。 一方HE-QUO要素は新たな埋め込み部分を開始する。
1行が十分に長ければ、このテキストは次の様に整形される:
5WERBEH 4WERBEH english3 2WERBEH 1WERBEH
8WERBEH 7WERBEH 6WERBEH
english9 english10 english11 13WERBEH 12WERBEH
english14 english15 english16
english17 20WERBEH english19 18WERBEH
HE-QUO要素の埋め込みによって、HEBREW18とenglish19が入れ替わっていることに注意せよ。
1行が短くて改行が必要なら、次の様になる:
2WERBEH 1WERBEH
-EH 4WERBEH english3
5WERB
-EH 7WERBEH 6WERBEH
8WERB
english9 english10 en-
glish11 12WERBEH
13WERBEH
english14 english15
english16
english17 18WERBEH
20WERBEH english19
HEBREW18をenglish19より先に読ませる必要があるので、HEBREW18はenglish19より上の行に整形される。 無改行時の整形に改行を挿入するだけという単純なことにはならないのである。 また、english19から始まる文字列は前の行に入れることもできたのに、そうなっていないことに注意せよ。 これは、書字方向が右から左である文中に、左から右に書かれる単語が出てくる時に(あるいはその逆の時に)、単語を次の行へつなぐハイフンが行の途中で出現しないようにするためである。