9 視覚フォーマットモデル

目次

9.1 視覚フォーマットモデルの概要

この章と次の章では、視覚フォーマットモデルについて説明します。これは、ユーザーエージェントが視覚的なメディアに対してドキュメントツリーをどのように処理するかを示します。

視覚フォーマットモデルでは、ドキュメントツリー内の各要素がボックスモデルに従って0個以上のボックスを生成します。これらのボックスのレイアウトは以下によって制御されます:

この章と次の章で定義されたプロパティは、連続メディアおよびページ化メディアの両方に適用されます。 ただし、マージンプロパティの意味はページ化メディアに適用される場合に異なります(詳細はページモデルを参照してください)。

視覚フォーマットモデルは、すべてのフォーマットの側面を指定しているわけではありません(例: 文字間隔アルゴリズムの指定はありません)。準拠するユーザーエージェントは、この仕様でカバーされていないフォーマットの問題について異なる動作をする場合があります。

9.1.1 ビューポート

連続メディア用のユーザーエージェントは通常、ユーザーにドキュメントを閲覧するためのビューポート(画面上のウィンドウまたはその他の表示領域)を提供します。ユーザーエージェントは、ビューポートがリサイズされた場合にドキュメントのレイアウトを変更することがあります(初期包含ブロックを参照)。

ビューポートがドキュメントがレンダリングされているキャンバス領域よりも小さい場合、ユーザーエージェントはスクロール機構を提供する必要があります。 各キャンバスにつきビューポートは1つだけですが、ユーザーエージェントは複数のキャンバスにレンダリングを行うことができます(例: 同じドキュメントの異なるビューを提供する)。

9.1.2 包含ブロック

CSS 2.2では、多くのボックスの位置とサイズが、包含ブロックと呼ばれる長方形のボックスのエッジに基づいて計算されます。 一般的に、生成されたボックスは子孫ボックスの包含ブロックとして機能します。ボックスがその子孫の包含ブロックを「確立する」と言います。「ボックスの包含ブロック」というフレーズは、「ボックスが存在する包含ブロック」を意味し、ボックスが生成するものではありません。

各ボックスはその包含ブロックに対して位置が与えられますが、この包含ブロックに制約されるわけではなく、オーバーフローすることがあります。

包含ブロックの寸法がどのように計算されるかの詳細次の章で説明されています。

9.2 ボックス生成の制御

以下のセクションでは、CSS 2.2で生成される可能性のあるボックスの種類について説明します。ボックスの種類は、視覚フォーマットモデルでの動作に部分的に影響を与えます。以下で説明する'display'プロパティは、ボックスの種類を指定します。

'display'プロパティの特定の値は、ソースドキュメントの要素に対して、子孫ボックスや生成されたコンテンツを含み、さらに任意の位置決めスキームに関与する主要ボックスを生成させます。一部の要素は、主要ボックスに加えて追加のボックスを生成する場合があります。例えば、'list-item'要素です。これらの追加ボックスは、主要ボックスに基づいて配置されます。

9.2.1 ブロックレベル要素とブロックボックス

ブロックレベル要素– ソースドキュメントの中で視覚的にブロックとしてフォーマットされる要素(例: 段落)– は、ブロックレベルの主要ボックスを生成する要素です。'display'プロパティの値で要素をブロックレベルにするものには、'block'、'list-item'、および'table'があります。ブロックレベルボックスは、ブロックフォーマットコンテキストに参加するボックスです。

CSS 2.2では、ブロックレベルボックスはテーブルボックスまたは置換要素の主要ボックスでない限り、ブロックコンテナーボックスでもあります。ブロックコンテナーボックスは、ブロックレベルボックスのみを含むか、インラインフォーマットコンテキストを確立し、インラインレベルボックスのみを含みます。主要ボックスがブロックコンテナーボックスである要素は、ブロックコンテナー要素です。'display'プロパティの値で非置換要素がブロックコンテナーボックスを生成するものには、'block'、'list-item'、および'inline-block'があります。ただし、すべてのブロックコンテナーボックスがブロックレベルボックスであるわけではありません。非置換インラインブロックや非置換テーブルセルはブロックコンテナーボックスですが、ブロックレベルではありません。ブロックコンテナーボックスであり、かつブロックレベルであるボックスは、ブロックボックスと呼ばれます。

"ブロックレベルボックス"、"ブロックコンテナーボックス"、および"ブロックボックス"の3つの用語は、明確な場合には"ブロック"と省略されることがあります。

9.2.1.1 匿名ブロックボックス

次のようなドキュメントでは:


<DIV>
  Some text
  <P>More text
</DIV>

(DIVとPの両方に'display: block'が指定されていると仮定すると)、DIVはインラインコンテンツとブロックコンテンツの両方を持っているように見えます。フォーマットを定義しやすくするために、「Some text」の周囲に匿名ブロックボックスがあると仮定します。

上記の例における3つのボックスの図解。一つは匿名ボックス。   [D]

上記の例における3つのボックスの図解。一つは匿名ボックス。

言い換えると、ブロックコンテナーボックス(上記のDIVのように)にブロックレベルボックス(上記のPのように)が含まれている場合、内部にはのみブロックレベルボックスを含むようにします。

インラインボックスがインフローブロックレベルボックスを含む場合、インラインボックス(および同じ行ボックス内のインライン祖先)は、ブロックレベルボックス(および連続しているか折り畳み可能な空白やアウトオブフロー要素でのみ分離されたブロックレベル兄弟)を挟んで分割され、インラインボックスが2つのボックスに分割されます(どちらか片側が空の場合でも)。行ボックスの前後は匿名ブロックボックスで囲まれ、ブロックレベルボックスはそれら匿名ボックスの兄弟になります。そのようなインラインボックスが相対位置指定の影響を受ける場合、結果として生じる変換はインラインボックス内のブロックレベルボックスにも影響します。

例:

以下のCSSルールが適用される場合、このモデルは次の例に適用されます:


p    { display: inline }
span { display: block }

このHTML文書を使用すると:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HEAD>
<TITLE>Anonymous text interrupted by a block</TITLE>
</HEAD>
<BODY>
<P>
This is anonymous text before the SPAN.
<SPAN>This is the content of SPAN.</SPAN>
This is anonymous text after the SPAN.
</P>
</BODY>

P要素には匿名テキストのチャンク(C1)が含まれ、その後にブロックレベル要素が続き、さらに匿名テキストのチャンク(C2)が続きます。結果として得られるボックスは、BODYを表すブロックボックスであり、C1の周囲に匿名ブロックボックス、SPANのブロックボックス、そしてC2の周囲に別の匿名ブロックボックスが含まれます。

匿名ボックスのプロパティは、囲んでいる非匿名ボックス(例: 「匿名ブロックボックス」のサブセクション見出し直下の例ではDIV)のプロパティを継承します。継承されないプロパティはその初期値を持ちます。例えば、匿名ボックスのフォントはDIVから継承されますが、マージンは0になります。

匿名ブロックボックスを生成する原因となる要素に設定されたプロパティは、その要素のボックスとコンテンツに適用されます。例えば、上記の例でP要素にボーダーが設定されていた場合、そのボーダーはC1(行の終わりで開いた状態)とC2(行の始まりで開いた状態)の周囲に描画されます。

一部のユーザーエージェントは、ブロックを含むインラインにボーダーを別の方法で実装しています。例えば、そのようなネストされたブロックを「匿名ラインボックス」で囲み、そのようなボックスの周囲にインラインボーダーを描画する方法です。CSS1およびCSS2がこの動作を定義していなかったため、CSS1およびCSS2のみを対象としたユーザーエージェントは、この代替モデルを実装し、このCSS 2.2の部分に準拠していると主張することができます。この仕様がリリースされた後に開発されたUAには適用されません。

匿名ブロックボックスは、それを参照する可能性のあるパーセンテージ値を解決する際に無視されます。代わりに、最も近い非匿名の祖先ボックスが使用されます。例えば、上記のDIV内の匿名ブロックボックスの子がパーセンテージの高さを解決するために包含ブロックの高さを知る必要がある場合、匿名ブロックボックスの高さではなく、DIVによって形成された包含ブロックの高さを使用します。

9.2.2 インラインレベル要素とインラインボックス

インラインレベル要素は、ソースドキュメント内で新しいコンテンツブロックを形成せず、コンテンツが行内に分配される要素です(例: 段落内の強調されたテキスト、インライン画像など)。'display'プロパティの次の値が要素をインラインレベルにします: 'inline'、'inline-table'、および'inline-block'。 インラインレベル要素はインラインレベルボックスを生成します。これらはインラインフォーマットコンテキストに参加するボックスです。

インラインボックスとは、インラインレベルであり、そのコンテンツが包含するインラインフォーマットコンテキストに参加するボックスのことです。'display'値が'inline'の非置換要素は、インラインボックスを生成します。 インラインボックスでないインラインレベルボックス(例: 置換インラインレベル要素、インラインブロック要素、インラインテーブル要素)は、アトミックインラインレベルボックスと呼ばれます。これらは単一の不透明なボックスとしてインラインフォーマットコンテキストに参加します。

9.2.2.1 匿名インラインボックス

ブロックコンテナー要素内に直接含まれるテキスト(インライン要素内ではない)は、匿名インライン要素として扱われなければなりません。

次のようなHTMLマークアップを含むドキュメントでは:


<p>Some <em>emphasized</em> text</p>

<p>はブロックボックスを生成し、その中にいくつかのインラインボックスが含まれます。「emphasized」のボックスはインライン要素(<em>)によって生成されたインラインボックスですが、その他のボックス(「Some」および「text」)はブロックレベル要素(<p>)によって生成されたインラインボックスです。後者は匿名インラインボックスと呼ばれます。なぜなら、それらには関連付けられたインラインレベル要素がないからです。

このような匿名インラインボックスは、親ブロックボックスから継承可能なプロパティを継承します。継承されないプロパティは初期値を持ちます。この例では、匿名インラインボックスの色はPから継承されますが、背景は透明になります。

'white-space'プロパティに従って後で折りたたまれることになる空白コンテンツは、匿名インラインボックスを生成しません。

文脈からどの種類の匿名ボックスを指しているかが明らかな場合、この仕様では匿名インラインボックスと匿名ブロックボックスを単に匿名ボックスと呼びます。

テーブルをフォーマットする際に発生するその他の種類の匿名ボックスについては、テーブルを参照してください。

9.2.3 ランインボックス

[このセクションは、セクション番号を以前のドラフトと一致させるために存在します。'Display: run-in'は現在、CSSレベル3で定義されています(CSS基本ボックスモデルを参照してください)。]

9.2.4 The 'display' プロパティ

名前: display
値: inline | block | list-item | inline-block | 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
初期値: inline
適用対象: すべての要素
継承: no
パーセンテージ: N/A
メディア: all
計算値: テキストを参照

このプロパティの値には次のような意味があります:

block
この値は要素に主要なブロックボックスを生成させます。
inline-block
この値は要素に主要なインラインレベルのブロックコンテナーを生成させます。 (インラインブロックの内部はブロックボックスとしてフォーマットされ、要素自体はアトミックインラインレベルボックスとしてフォーマットされます。)
inline
この値は要素に1つ以上のインラインボックスを生成させます。
list-item
この値は要素(例: HTMLのLI)に主要なブロックボックスとマーカーボックスを生成させます。リストに関する情報とそのフォーマット例については、リストのセクションを参照してください。
none
この値は、要素がフォーマット構造に現れないようにします(つまり、視覚メディアでは要素はボックスを生成せず、レイアウトに影響を与えません)。子孫要素もボックスを生成せず、要素とそのコンテンツはフォーマット構造から完全に削除されます。この動作は、子孫に'display'プロパティを設定しても上書きすることはできません

'none'のディスプレイ値は不可視のボックスを作成するのではなく、まったくボックスを作成しません。CSSには、フォーマット構造にボックスを生成し、それ自体は目に見えないボックスを生成するメカニズムが含まれています。詳細は可視性のセクションを参照してください。

table, inline-table, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, and table-caption
これらの値は、要素をテーブルの章で説明されている制限に従って、テーブル要素のように振る舞わせます。

計算値は指定値と同じですが、配置された要素やフロート要素('display'、'position'、および'float'の関係を参照)およびルート要素の場合は例外があります。 ルート要素の場合、計算値は'display'、'position'、および'float'の関係のセクションで説明されるように変更されます。

初期値'display'の場合、'inline'ですが、ユーザーエージェントのデフォルトスタイルシートのルールによって上書きされる可能性があります。HTML 4のサンプルスタイルシートを参照してください。

例:

'display'プロパティのいくつかの例を以下に示します:


p   { display: block }
em  { display: inline }
li  { display: list-item } 
img { display: none }      /* 画像を表示しない */

9.3 位置決定スキーム

CSS 2.2では、ボックスは3つの位置決定スキームのいずれかに従って配置されます。

  1. 通常のフロー。CSS 2.2では、通常のフローはブロックレベルボックスのブロックフォーマット、 インラインレベルボックスのインラインフォーマット、およびブロックレベルおよびインラインレベルボックスの相対位置指定を含みます。
  2. フロート。フロートモデルでは、ボックスはまず通常のフローに従って配置され、その後フローから外されて可能な限り左または右に移動されます。コンテンツはフロートの側面に沿って流れることがあります。
  3. 絶対位置指定。絶対位置指定モデルでは、ボックスは完全に通常のフローから外され(後続の兄弟要素に影響を与えません)、包含ブロックに基づいて位置が割り当てられます。

要素がフロート、絶対位置に指定されている、またはルート要素である場合、その要素はフローから外れたと呼ばれます。要素がフローから外れていない場合、それはフロー内と呼ばれます。 要素Aのフローは、Aと、最も近いフロー外の祖先がAであるすべてのフロー内要素から構成される集合です。

注意。 CSS 2.2の位置決定スキームは、レイアウト効果のために使用されるマークアップトリック(例: 見えない画像)を避けることで、文書をよりアクセス可能にするための支援を提供します。

9.3.1 位置決定スキームの選択: 'position' プロパティ

'position'プロパティおよび'float'プロパティは、ボックスの位置を計算するために使用されるCSS 2.2の位置決定アルゴリズムを決定します。

名前: position
値: static | relative | absolute | fixed | inherit
初期値: static
適用対象: すべての要素
継承: no
パーセンテージ: N/A
メディア: visual
計算値: 指定通り

このプロパティの値には次の意味があります:

static
ボックスは通常のボックスであり、通常のフローに従って配置されます。 'top''right''bottom'、 および'left'プロパティは適用されません。
relative
ボックスの位置は通常のフローに従って計算されます(これを通常のフローでの位置と呼びます)。その後、ボックスは通常の位置に対して相対的にオフセットされます。 ボックスBが相対位置指定されている場合、次のボックスの位置は、Bがオフセットされていないかのように計算されます。'position:relative'の効果は、table-row-group、table-header-group、table-footer-group、table-row、table-column-group、table-column、table-cell、およびtable-caption要素には未定義です。
absolute
ボックスの位置(および場合によってはサイズ)は、 'top''right''bottom'、 および'left' プロパティを使用して指定されます。これらのプロパティは、ボックスの包含ブロックに基づいてオフセットを指定します。 絶対位置指定されたボックスは通常のフローから外されます。これにより、後続の兄弟要素のレイアウトには影響を与えません。また、 絶対位置指定されたボックスにはマージンがありますが、他のマージンと折りたたまれません。
fixed
ボックスの位置は'absolute'モデルに従って計算されますが、さらにボックスは固定されます。 'absolute'モデルの場合と同様に、ボックスのマージンは他のマージンと折りたたまれません。 handheld、projection、screen、tty、およびtvメディアタイプの場合、ボックスはビューポートに対して固定され、スクロールしても移動しません。 printメディアタイプの場合、ボックスはすべてのページにレンダリングされ、ページボックスに対して固定されます(例えば、印刷プレビューの場合のようにビューポートを通してページが見える場合でも)。その他のメディアタイプについては、プレゼンテーションは未定義です。 作成者は'fixed'をメディアに依存する方法で指定することを望むかもしれません。例えば、作成者はボックスが画面上ではビューポートの上部に留まるようにしたいが、印刷された各ページの上部には留まらないようにしたいと考えるかもしれません。この2つの指定は、次のように@mediaルールを使用して分離できます:

例:

   
@media screen { 
  h1#first { position: fixed } 
}
@media print { 
  h1#first { position: static }
}

UAは固定ボックスのコンテンツをページ分割してはなりません。なお、UAは他の方法で不可視コンテンツを印刷する場合があります。「ページボックス外のコンテンツ」を章13で参照してください。

ユーザーエージェントは、ルート要素のpositionを'static'として扱うことがあります。

9.3.2 ボックスオフセット: 'top', 'right', 'bottom', 'left'

要素は、その'position'プロパティの値が'static'以外である場合、配置済みとされます。配置済みの要素は、次の4つのプロパティに基づいてレイアウトされる配置ボックスを生成します:

名前: top
値: <length> | <percentage> | auto | inherit
初期値: auto
適用対象: 配置済み要素
継承: なし
パーセンテージ: 包含ブロックの高さに基づく
メディア: ビジュアル
計算値: 長さとして指定された場合、対応する絶対長さ。パーセンテージとして指定された場合、指定された値。それ以外の場合は'auto'。

このプロパティは、絶対配置されたボックスのトップマージンエッジが、ボックスの包含ブロックの上端からどの程度オフセットされるかを指定します。相対配置されたボックスの場合、オフセットはボックス自体の上端に対して行われます(つまり、ボックスは通常のフローで位置が決定され、その位置からこれらのプロパティに基づいてオフセットされます)。

名前: right
値: <length> | <percentage> | auto | inherit
初期値: auto
適用対象: 配置済み要素
継承: なし
パーセンテージ: 包含ブロックの幅に基づく
メディア: ビジュアル
計算値: 長さとして指定された場合、対応する絶対長さ。パーセンテージとして指定された場合、指定された値。それ以外の場合は'auto'。

'top'と同様ですが、ボックスの右マージンエッジがボックスの包含ブロックの右端から左方向にどの程度オフセットされるかを指定します。相対配置されたボックスの場合、オフセットはボックス自体の右端に対して行われます。

名前: bottom
値: <length> | <percentage> | auto | inherit
初期値: auto
適用対象: 配置済み要素
継承: なし
パーセンテージ: 包含ブロックの高さに基づく
メディア: ビジュアル
計算値: 長さとして指定された場合、対応する絶対長さ。パーセンテージとして指定された場合、指定された値。それ以外の場合は'auto'。

'top'と同様ですが、ボックスの下マージンエッジがボックスの包含ブロックの下端から上方向にどの程度オフセットされるかを指定します。相対配置されたボックスの場合、オフセットはボックス自体の下端に対して行われます。

名前: left
値: <length> | <percentage> | auto | inherit
初期値: auto
適用対象: 配置済み要素
継承: なし
パーセンテージ: 包含ブロックの幅に基づく
メディア: ビジュアル
計算値: 長さとして指定された場合、対応する絶対長さ。パーセンテージとして指定された場合、指定された値。それ以外の場合は'auto'。

'top'と同様ですが、ボックスの左マージンエッジがボックスの包含ブロックの左端から右方向にどの程度オフセットされるかを指定します。相対配置されたボックスの場合、オフセットはボックス自体の左端に対して行われます。

これら4つのプロパティの値は次の意味を持ちます:

<length>
オフセットは参照エッジからの固定距離です。負の値も許容されます。
<percentage>
オフセットは包含ブロックの幅('left'または'right'の場合)または高さ('top'および'bottom'の場合)のパーセンテージです。負の値も許容されます。
auto
置換されていない要素の場合、この値の影響は関連プロパティのどれが'auto'であるかによります。詳細は高さ絶対配置された置換されていない要素のセクションを参照してください。置換された要素の場合、この値の影響は置換コンテンツの固有寸法にのみ依存します。詳細は高さの絶対配置された置換要素のセクションを参照してください。

9.4 通常のフロー

通常のフロー内のボックスはフォーマットコンテキストに属し、CSS 2.2ではテーブル、ブロック、インラインのいずれかです。CSSの将来のレベルでは、他の種類のフォーマットコンテキストが導入される予定です。ブロックレベルのボックスはブロックフォーマットコンテキストに参加します。インラインレベルのボックスインラインフォーマットコンテキストに参加します。テーブルフォーマットコンテキストについては、テーブルに関する章をご参照ください。

9.4.1 ブロックフォーマットコンテキスト

フロート、絶対配置された要素、ブロックコンテナ(例: inline-block、table-cell、table-captionなど)でブロックボックスでないもの、および'overflow'が'visible'以外の値を持つブロックボックス(ただしその値がビューポートに伝播された場合を除く)は、そのコンテンツのために新しいブロックフォーマットコンテキストを確立します。

ブロックフォーマットコンテキストでは、ボックスは包含ブロックの上端から始まり、縦方向に順番に配置されます。2つの隣接するボックス間の縦方向の距離は'margin'プロパティによって決定されます。ブロックフォーマットコンテキスト内の隣接ブロックレベルボックス間の縦方向マージンは折り畳まれます

ブロックフォーマットコンテキストでは、各ボックスの左外端は包含ブロックの左端に接触します(右から左のフォーマットの場合は右端が接触)。これは、フロートが存在する場合でも当てはまります(ただし、ボックスの行ボックスがフロートによって縮小する可能性があります)。ただし、ボックス自体が新しいブロックフォーマットコンテキストを確立する場合(その場合、ボックス自体がフロートによって狭くなる可能性があります)。

ページメディアにおける改ページについての情報は、許可された改ページに関するセクションをご参照ください。

9.4.2 インラインフォーマットコンテキスト

インラインフォーマットコンテキストは、ブロックレベルのボックスを含まないブロックコンテナボックスによって確立されます。インラインフォーマットコンテキストでは、ボックスは包含ブロックの上部から始まり、横方向に順番に配置されます。これらのボックス間では、水平マージン、ボーダー、パディングが尊重されます。ボックスは、上下やベースラインの位置に基づいて垂直方向に整列することができます。これらのボックスが形成する行を含む矩形領域は行ボックスと呼ばれます。

行ボックスの幅は、包含ブロックとフロートの存在によって決まります。行ボックスの高さは、行の高さの計算に関するセクションで示される規則によって決まります。

行ボックスは、それが含むすべてのボックスにとって十分な高さを持ちます。ただし、含まれる最も高いボックスよりも高くなる場合があります(例えば、ボックスがベースラインに整列するように配置されている場合など)。ボックスBの高さがそれを含む行ボックスの高さよりも小さい場合、Bの行ボックス内での垂直方向の整列は'vertical-align'プロパティによって決まります。1つの行ボックス内に複数のインラインレベルのボックスが水平に収まらない場合、それらは2つ以上の縦方向に積み重ねられた行ボックスに分配されます。このようにして、段落は行ボックスの縦方向のスタックとなります。行ボックスは、他に指定がない限り垂直方向に分離されることはなく、重なることもありません。

一般的に、行ボックスの左端はその包含ブロックの左端に接触し、右端は包含ブロックの右端に接触します。ただし、フロートするボックスが包含ブロックの端と行ボックスの端の間に入る場合があります。このため、同じインラインフォーマットコンテキスト内の行ボックスは一般的に同じ幅(包含ブロックの幅)を持ちますが、フロートによって利用可能な水平空間が減少すると幅が異なる場合があります。同じインラインフォーマットコンテキスト内の行ボックスは通常、高さが異なります(例: ある行には高い画像が含まれ、他の行にはテキストのみが含まれる場合など)。

行内のインラインレベルボックスの総幅がそれを含む行ボックスの幅よりも小さい場合、行ボックス内でのそれらの水平分布は'text-align'プロパティによって決まります。このプロパティの値が'justify'の場合、ユーザーエージェントはインラインボックス内のスペースや単語を伸ばすこともできます(ただし、inline-tableやinline-blockボックスは対象外)。

インラインボックスが行ボックスの幅を超える場合、それは複数のボックスに分割され、これらのボックスが複数の行ボックスに分配されます。インラインボックスが���割できない場合(例えば、インラインボックスが単一の文字を含む場合、言語固有の単語分割規則がその中での改行を許可しない場合、またはインラインボックスがnowrapやpreのwhite-space値の影響を受けている場合など)、インラインボックスは行ボックスをオーバーフローします。

インラインボックスが分割されると、マージン、ボーダー、パディングは分割が発生した場所(または複数の分割がある場合は任意の分割地点)で視覚的な影響を及ぼしません。

インラインボックスは、双方向テキスト処理のために、同じ行ボックス内で複数のボックスに分割されることもあります。

インラインフォーマットコンテキスト内では、インラインレベルのコンテンツを保持するために必要に応じて行ボックスが作成されます。テキスト、保持された空白、ゼロ以外のマージン、パディング、ボーダーを持つインライン要素、その他のフロー内コンテンツ(例えば画像、インラインブロックやインラインテーブル)を含まず、保持された改行で終了しない行ボックスは、内部の要素の位置を決定する目的でゼロ高さの行ボックスとして扱われる必要があり、それ以外の目的では存在しないものとして扱われる必要があります。

次はインラインボックス構造の例です。以下の段落(HTMLブロックレベル要素Pによって作成)は、EM要素とSTRONG要素が混在する匿名のテキストを含みます:


<P>Several <EM>emphasized words</EM> appear
<STRONG>in this</STRONG> sentence, dear.</P>

P要素は、5つのインラインボックス(そのうち3つは匿名)を含むブロックボックスを生成します:

段落をフォーマットするために、ユーザーエージェントはこれら5つのボックスを行ボックスに流します。この例では、P要素によって生成されるボックスが行ボックスの包含ブロックを確立します。包含ブロックが十分に広い場合、すべてのインラインボックスは単一の行ボックスに収まります:

 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つのEMボックス("split1"と"split2"と呼ぶ)に分割されました。マージン、ボーダー、パディング、またはテキスト装飾は、split1の後やsplit2の前に視覚的な影響を及ぼしません。

次の例を考えてみましょう:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>複数行にわたるインラインフローの例</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の幅に応じて、ボックスは次のように分配される場合があります:

行分割の影響を示す画像   [D]

9.4.3 相対配置

ボックスが通常のフローまたはフロートに従ってレイアウトされた後、その位置に対して相対的にシフトすることができます。これを相対配置と呼びます。この方法でボックス(B1)をオフセットしても、後続のボックス(B2)には影響しません:B2は、B1がオフセットされていないかのように位置が与えられ、B2はB1のオフセットが適用された後も再配置されません。これは、相対配置がボックスを重ねる可能性があることを意味します。しかし、相対配置によって'overflow:auto'または'overflow:scroll'のボックスがオーバーフローした場合、ユーザーエージェントはこのコンテンツ(オフセット位置で)にアクセスできるようにする必要があり、これはスクロールバーの作成を通じてレイアウトに影響を与える可能性があります。

相対配置されたボックスは、通常のフローのサイズを保持し、改行や元々予約されていたスペースを含みます。包含ブロックに関するセクションでは、相対配置されたボックスが新しい包含ブロックを確立するタイミングについて説明しています。

相対配置された要素に対して、'left'と'right'はボックスを水平方向に移動させますが、そのサイズは変更しません。'left'はボックスを右に移動させ、'right'はボックスを左に移動させます。'left'または'right'によってボックスが分割または伸縮されることはないため、使用される値は常に:left = -rightとなります。

両方の'left'と'right'が'auto'(初期値)の場合、使用される値は'0'です(つまり、ボックスは元の位置に留まります)。

'left'が'auto'の場合、その使用される値は'right'の値のマイナスとなります(つまり、ボックスは'right'の値だけ左に移動します)。

'right'が'auto'として指定された場合、その使用される値は'left'の値のマイナスとなります。

'left'と'right'のどちらも'auto'ではない場合、位置が過度に制約され、いずれかが無視される必要があります。包含ブロックの'direction'プロパティが'ltr'の場合、'left'の値が優先され、'right'は-'left'になります。包含ブロックの'direction'が'rtl'の場合、'right'が優先され、'left'は無視されます。

例:

例。 次の3つのルールは等価です:


div.a8 { position: relative; direction: ltr; left: -1em; right: auto }
div.a8 { position: relative; direction: ltr; left: auto; right: 1em }
div.a8 { position: relative; direction: ltr; left: -1em; right: 5em }

'top'と'bottom'プロパティは、相対配置された要素をサイズを変更せずに上下に移動させます。'top'はボックスを下に移動させ、'bottom'はボックスを上に移動させます。'top'または'bottom'によってボックスが分割または伸縮されることはないため、使用される値は常に:top = -bottomとなります。両方が'auto'の場合、その使用される値は両方とも'0'です。一方が'auto'の場合、それは他方のマイナスとなります。どちらも'auto'でない場合、'bottom'は無視されます(つまり、'bottom'の使用される値は'top'の値のマイナスになります)。

注記。 相対配置されたボックスを動的に移動させると、スクリプト環境でアニメーション効果を生成できます('visibility'プロパティも参照してください)。 相対配置は上付き文字や下付き文字の形式として使用されることがありますが、位置決めを考慮して行の高さが自動的に調整されるわけではありません。詳細については、行の高さの計算の説明を参照してください。

相対配置の例は、通常のフロー、フロート、絶対配置の比較に関するセクションに記載されています。

9.5 フロート

フロートとは、現在の行で左または右にシフトされたボックスのことです。フロート(または"フロートされた"ボックスや"フロート中"のボックス)の最も興味深い特徴は、コンテンツがその側面に沿って流れることができる(または'clear'プロパティによって防止される)点です。左にフロートされたボックスの右側、右にフロートされたボックスの左側にコンテンツが流れます。以下ではフロートの位置設定とコンテンツの流れについて紹介します。フロートの挙動を支配する正確なルール'float'プロパティの説明に記載されています。

フロートされたボックスは、外側の端が包含ブロックの端または別のフロートの外側の端に触れるまで左または右にシフトされます。行ボックスがある場合、フロートされたボックスの外側の上端は現在の行ボックスの上端に揃えられます。

フロートを収めるための水平スペースが十分でない場合、フロートはフィットするか、他にフロートが存在しなくなるまで下方にシフトされます。

フロートはフロー内にないため、フロートボックスの前後に作成される位置指定されていないブロックボックスは、フロートが存在しないかのように垂直方向に流れます。しかし、フロートの隣で作成される現在および後続の行ボックスは、フロートのマージンボックスにスペースを確保するために必要に応じて短縮されます。

行ボックスがフロートの隣にあるとは、次の4つの条件すべてを満たす垂直位置が存在する場合を指します:(a)行ボックスの上端と同じかそれ以下、(b)行ボックスの下端と同じかそれ以上、(c)フロートの上マージンエッジより下、(d)フロートの下マージンエッジより上。

注記:これは、高さがゼロまたは負の外側の高さを持つフロートが行ボックスを短縮しないことを意味します。

短縮された行ボックスがコンテンツを収めるには小さすぎる場合、その行ボックスは下方にシフトされ(その幅が再計算され)、コンテンツが収まるか、他のフロートが存在しなくなるまで続きます。フロートボックスの前の現在の行内のコンテンツは、同じ行でフロートの反対側に再フローされます。つまり、インラインレベルのボックスが左フロートに遭遇する前に行内に配置されており、それが残りの行ボックススペースに収まる場合、左フロートはその行に配置され、行ボックスの上端に揃えられ、行内のインラインレベルのボックスはフロートの右側(左フロートの反対側)に移動します。rtlと右フロートの場合も同様です。

テーブル、ブロックレベルの置換要素、または通常のフロー内で新しいブロックフォーマットコンテキストを確立する要素(例:'overflow'が'visible'以外の値を持つ要素)のボーダーボックスは、同じブロックフォーマットコンテキスト内のフロートのマージンボックスと重なってはなりません。必要に応じて、実装はその要素を前のフロートの下に配置することでクリアするべきですが、十分なスペースがある場合はそのフロートの隣に配置してもかまいません。その要素のボーダーボックスをセクション10.3.3で定義されているよりも狭くすることもできます。CSS2では、その要素をフロートの隣に配置するタイミングや、その要素がどの程度狭くなるかについて定義していません。

例:

例。 次のドキュメント断片では、包含ブロックがフロートの隣にコンテンツを収めるには狭すぎるため、コンテンツがフロートの下に移動し、text-alignプロパティに基づいて行ボックス内に整列されます。


p { width: 10em; border: solid aqua; }
span { float: left; width: 5em; height: 5em; border: solid blue; }


...


<p>
  <span> </span>
  Supercalifragilisticexpialidocious
</p>

この断片は次のように見える可能性があります:

包含ブロックが狭すぎるためフロートのすぐ下に再配置されたコンテンツの例を示す画像

複数のフロートが隣接する場合もあり、このモデルは同じ行内の隣接するフロートにも適用されます。

例:

次のルールは、class="icon"を持つすべてのIMGボックスを左にフロートさせ(左マージンを'0'に設定)、次のようになります:


img.icon { 
  float: left;
  margin-left: 0;
}

次のHTMLソースとスタイルシートを考えてみてください:

  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>フロートの例</TITLE>
    <STYLE type="text/css">
      IMG { float: left }
      BODY, P, IMG { margin: 2em }
    </STYLE>
  </HEAD>
  <BODY>
    <P><IMG src=img.png alt="フロートを説明する画像">
       他にテキストがないサンプルテキスト...
  </BODY>
</HTML>

IMGボックスは左にフロートされます。その後のコンテンツは、フロートの右側に、フロートと同じ行からフォーマットされます。フロートの存在により右側の行ボックスは短縮されますが、フロートの後では再び「通常の」幅(P要素によって確立された包含ブロックの幅)に戻ります。このドキュメントは次のようにフォーマットされる可能性があります:

フロートボックスがマージンにどのように影響するかを示す画像   [D]

ドキュメントが次のようになっていても、フォーマットは同じになります:


<BODY>
  <P>Some sample text 
  <IMG src=img.png alt="フロートを説明する画像">
           他にテキストがないサンプルテキスト...
</BODY>

なぜなら、フロートの左側のコンテンツはフロートによって押しのけられ、右側に再配置されるからです。

セクション8.3.1で述べられているように、フロートボックスのマージンは隣接するボックスのマージンと折り畳まれることはありません。このため、前述の例では、PボックスとフロートされたIMGボックスとの間の垂直マージンは折り畳まれることはありません。

フロートの内容は、フロートが新しいスタッキングコンテキストを生成すると仮定して積み重ねられます。ただし、実際に新しいスタッキングコンテキストを生成する位置指定された要素や要素は、フロートの親スタッキングコンテキストに参加します。フロートは通常のフローボックスと重なることがあります(例:フロートの隣にある通常のフローボックスが負のマージンを持つ場合)。この場合、フロートは位置指定されていないインフローブロックの前にレンダリングされますが、インフローインラインの後ろにレンダリングされます。

例:

ここでは、フロートが通常のフロー内の要素のボーダーと重なる場合に何が起こるかを示す図を示します。

フロートボックスが2つの段落のボーダーと重なった様子を示す画像   [D]

フロート画像が重なったブロックボックスのボーダーを隠しています。

次の例は、'clear'プロパティを使用して、コンテンツがフロートの隣に流れるのを防ぐ方法を示しています。

例:

次のようなルールを仮定します:


p { clear: left }

フォーマットは次のようになります:

左フロートと'clear: left'の効果を示す段落2つの画像   [D]

両方の段落で'clear: left'が設定されており、2番目の段落がフロートの下の位置に押し下げられています。この処理は、clearプロパティ('clear')を使用して上位マージンにクリアランスを追加することで実現されます。

9.5.1 フロートの配置: 'float' プロパティ

名前: float
値: left | right | none | inherit
初期値: none
適用対象: すべて。ただし、9.7を参照
継承: no
パーセンテージ: N/A
メディア: ビジュアル
計算値: 指定された通り

このプロパティは、ボックスを左、右、または全くフロートさせるかどうかを指定します。どの要素にも設定できますが、絶対配置されたボックスを生成しない要素にのみ適用されます。このプロパティの値の意味は次の通りです:

left
要素は左にフロートされたブロックボックスを生成します。コンテンツはボックスの右側に、上端から流れます('clear'プロパティの影響を受けます)。
right
'left'と同様ですが、ボックスが右にフロートされ、コンテンツはボックスの左側に、上端から流れます。
none
ボックスはフロートされません。

ユーザーエージェントは、ルート要素のfloatを'none'として扱う場合があります。

以下にフロートの挙動を規定する正確なルールを示します:

  1. 左にフロートするボックスの左外側エッジは、その包含ブロックの左端より左に配置されてはなりません。右にフロートする要素についても同様のルールが適用されます。
  2. 現在のボックスが左にフロートし、ソースドキュメント内でそれ以前に生成された左フロートボックスが存在する場合、現在のボックスの左外側エッジは、以前のボックスの右外側エッジより右にあるか、またはその上端が以前のボックスの下端より下にある必要があります。右フロートボックスについても同様のルールが適用されます。
  3. 左フロートボックスの右外側エッジは、その隣の右フロートボックスの左外側エッジより右に配置されてはなりません。右フロート要素についても同様のルールが適用されます。
  4. フロートボックスの外側上端は、その包含ブロックの上端より上に配置されてはなりません。フロートが2つの折り畳まれたマージンの間にある場合、フロートは、フローに参加する他に空の匿名ブロック親が存在するかのように配置されます。その親の位置は、マージン折り畳みに関するセクションのルールによって定義されます。
  5. フロートボックスの外側上端は、ソースドキュメント内でそれ以前に生成されたブロックまたはフロートボックスの外側上端より上に配置されてはなりません。
  6. 要素のフロートボックスの外側上端は、ソースドキュメント内でそれ以前に生成されたボックスを含む行ボックスの上端より上に配置されてはなりません。
  7. 左にフロートするボックスがその左側に別の左フロートボックスを持つ場合、その右外側エッジは包含ブロックの右端より右に配置されてはなりません(緩やかに言えば、左フロートは可能な限り左に配置されていない限り、右端を突き出してはなりません)。右フロート要素についても同様のルールが適用されます。
  8. フロートボックスは可能な限り高い位置に配置されなければなりません。
  9. 左にフロートするボックスは可能な限り左に、右にフロートするボックスは可能な限り右に配置されなければなりません。より高い位置が、より左/右に遠い位置よりも優先されます。

しかし、CSS 2.2では、ブロックフォーマットコンテキスト内にフロートの位置が、すべての負の垂直マージンをゼロに設定した場合の位置よりも上にあるようなインフローの負の垂直マージンがある場合、フロートの位置は未定義です。

これらのルールで参照される他の要素は、フロートと同じブロックフォーマットコンテキスト内の他の要素のみを指します。

例:

このHTML断片では、bが右にフロートします。

<P>a<SPAN style="float: right">b</SPAN></P>

P要素の幅が十分であれば、aとbは並びます。次のように見える場合があります:

ボックスの左側にa、右側にbがある

9.5.2 フロートの隣でのフロー制御: 'clear' プロパティ

名前: clear
値: none | left | right | both | inherit
初期値: none
適用対象: ブロックレベル要素
継承: no
パーセンテージ: N/A
メディア: ビジュアル
計算値: 指定された通り

このプロパティは、要素のボックスが以前のフロートボックスに隣接できない側を示します。'clear'プロパティは、要素自身の内部や他のブロックフォーマットコンテキスト内のフロートを考慮しません。

非フロートのブロックレベルボックスに適用された場合、このプロパティの値には以下の意味があります:

left
ボックスの上端エッジが、ソースドキュメント内で以前に生成された左フロートボックスの下外側エッジより下にあることを要求します。
right
ボックスの上端エッジが、ソースドキュメント内で以前に生成された右フロートボックスの下外側エッジより下にあることを要求します。
both
ボックスの上端エッジが、ソースドキュメント内で以前に生成された右フロートおよび左フロートボックスの下外側エッジより下にあることを要求します。
none
フロートに関してボックスの位置に制約はありません。

'none'以外の値は、潜在的にクリアランスを導入します。クリアランスはマージンの折り畳みを妨げ、要素のmargin-topの上部にスペースとして機能します。これは要素をフロートより垂直に押し上げるために使用されます。

'clear'が設定された要素のクリアランスの計算は、まず要素の上端エッジの仮想位置を決定することで行われます。この位置は、要素の'clear'プロパティが'none'だった場合、実際の上端エッジが存在したであろう位置です。

要素の上端エッジのこの仮想位置が関連するフロートを超えていない場合、クリアランスが導入され、8.3.1のルールに従ってマージンが折り畳まれます。

その後、クリアランスの量は次のうち大きい方に設定されます:

  1. クリアされる最下部のフロートの下外側エッジとブロックのボーダーエッジを一致させるために必要な量。
  2. ブロックの上端エッジをその仮想位置に配置するために必要な量。

あるいは、クリアランスは正確に、クリアされる最下部のフロートの下外側エッジとブロックのボーダーエッジを一致させるために必要な量に設定されます。

注意: 両方の挙動は、既存のWebコンテンツとの互換性の評価が保留されている間、許可されています。将来のCSS仕様では、いずれか一方が要求される予定です。

注意: クリアランスは負またはゼロになる可能性があります。

例:

例1. 簡略化のために、次の3つのボックスがあると仮定します: ボトムマージンがM1のブロックB1(子要素なし、パディングやボーダーなし)、高さHのフロートブロックF、トップマージンがM2のブロックB2(パディングやボーダーなし、子要素なし)。B2には'clear'が'both'に設定されています。また、B2が空でないと仮定します。

B2の'clear'プロパティを考慮しない場合、以下の図のような状況になります。B1とB2のマージンは折り畳まれます。B1の下ボーダーエッジがy = 0の場合、Fの上端はy = M1、B2の上端エッジはy = max(M1,M2)、Fの下端はy = M1 + Hになります。

フロートFがM2の上部マージンに侵入している図

B2がFの下にない、つまりクリアランスを追加する必要がある状況であると仮定します。つまり、次の条件が成り立ちます:

max(M1,M2) < M1 + H

クリアランスCを2回計算し、C1とC2のうち大きい方を保持します: C = max(C1,C2)。最初の方法は、B2の上端をFの下端と一致させることです。つまり、y = M1 + H。この場合、クリアランスが間にあるためにマージンが折り畳まれなくなります:

Fの下端 = B2の上端エッジ

M1 + H = M1 + C1 + M2

C1 = M1 + H - M1 - M2

= H - M2

2番目の計算では、B2の上端をそのまま保持します、つまりy = max(M1,M2)。この場合:

max(M1,M2) = M1 + C2 + M2

C2 = max(M1,M2) - M1 - M2

max(M1,M2) < M1 + Hであると仮定しているため、次が成り立ちます:

C2 = max(M1,M2) - M1 - M2 < M1 + H - M1 - M2 = H - M2

C2 < H - M2

そして、C1 = H - M2であるため、次が成り立ちます:

C2 < C1

したがって:

C = max(C1,C2) = C1

例:

例2. 負のクリアランスの例は次のような状況です。この場合、クリアランスは-1emです。(要素にはボーダーやパディングがないと仮定します):

<p style="margin-bottom: 4em">
  最初の段落。

<p style="float: left; height: 2em; margin: 0">
  フロート段落。

<p style="clear: left; margin-top: 3em">
  最後の段落。

説明: 'clear'がない場合、最初と最後の段落のマージンは折り畳まれ、最後の段落の上端エッジはフロート段落の上端と一致します。しかし、'clear'は上端エッジをフロートのに配置することを要求します。つまり、2em下に移動します。これによりクリアランスが導入されます。結果として、マージンはもはや折り畳まれず、クリアランスの量はクリアランス+margin-top = 2emとなるように設定されます。つまり、クリアランス = 2em - margin-top = 2em - 3em = -1emになります。

このプロパティがフロート要素に設定されると、フロートの配置に関するルールが修正され、追加の制約(#10)が加えられます:

注意. このプロパティはCSS1ではすべての要素に適用されました。 実装はこのプロパティをすべての要素でサポートしていた可能性があります。CSS2および現行標準では、'clear'プロパティはブロックレベル要素にのみ適用されます。そのため、著者はこのプロパティをブロックレベル要素にのみ使用すべきです。もし実装がインライン要素でのクリアをサポートしている場合、上記で説明したようにクリアランスを設定するのではなく、改行を強制し、1つ以上の空行ボックスを挿入するか(またはセクション9.5で説明されているように新しい行ボックスを下方にシフトすること)、クリアされたインラインの行ボックスの上端を対応するフロートボックスの下に移動させるべきです。

9.6 絶対配置

絶対配置モデルでは、ボックスはその包含ブロックに対して明確にオフセットされます。これは通常のフローから完全に削除され(後続の兄弟要素には影響を与えません)、絶対配置されたボックスは通常のフローチルド要素および絶対(ただし固定ではない)配置された子孫要素のために新しい包含ブロックを確立します。ただし、絶対配置された要素の内容は他のボックスの周りを流れません。他のボックスの内容を覆い隠したり、自身が覆い隠されたりする場合がありますが、これは重なるボックスのスタックレベルによります。

この仕様で言及される 絶対配置された要素(またはそのボックス)は、その要素の'position' プロパティが'absolute'または'fixed'の値を持つことを意味します。

9.6.1 固定配置

固定配置は絶対配置のサブカテゴリです。唯一の違いは、固定配置されたボックスの場合、包含ブロックがビューポートによって確立されることです。連続メディアの場合、固定ボックスはドキュメントがスクロールされても移動しません。この点で、固定背景画像に似ています。ページメディアの場合、固定位置のボックスはすべてのページで繰り返されます。これは、たとえば各ページの下部に署名を配置するのに便利です。ページ領域より大きい固定位置のボックスはクリップされます。初期の包含ブロックで見えない固定位置ボックスの部分は印刷されません。

著者は固定配置を使用してフレームのようなプレゼンテーションを作成できます。次のフレームレイアウトを考えてみてください:

position='fixed'を使用したフレームのようなレイアウトを示す画像   [D]

これは次のHTMLドキュメントとスタイルルールで実現できるかもしれません:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>CSSを使用したフレームドキュメント</TITLE>
    <STYLE type="text/css" media="screen">
      BODY { height: 8.5in } /* 以下のパーセンテージ高さのために必要 */
      #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>

9.7 『display』『position』および『float』の関係

ボックスの生成とレイアウトに影響を与える3つのプロパティ — 『display』『position』、 および 『float』 — は次のように相互作用します:

  1. 『display』が『none』の値を持つ場合、 『position』 および 『float』は適用されません。 この場合、要素はボックスを生成しません。
  2. それ以外の場合、 『position』が『absolute』または『fixed』の値を持つ場合、 ボックスは絶対配置され、 『float』の計算値は『none』となり、 『display』は以下の表に従って設定されます。 ボックスの位置は 『top』『right』『bottom』、 および 『left』 プロパティおよびボックスの包含ブロックによって決定されます。
  3. それ以外の場合、『float』が『none』以外の値を持つ場合、 ボックスはフロートされ、『display』は以下の表に従って設定されます。
  4. それ以外の場合、要素がルート要素である場合、 『display』は以下の表に従って設定されます。ただし、CSS 2.2では『list-item』の指定値が計算値の『block』または『list-item』になるかどうかは未定義です。
  5. それ以外の場合、残りの『display』プロパティ値は指定通りに適用されます。
指定値 計算値
inline-table table
inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block block
その他 指定値と同じ

9.8 通常のフロー、フロート、および絶対配置の比較

通常のフロー、相対配置、フロート、および絶対配置の違いを説明するために、次のHTMLを基にした一連の例を提供します:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>ポジショニングスキームの比較</TITLE>
  </HEAD>
  <BODY>
    <P>本文の内容の始まり。
      <SPAN id="outer"> 外側の内容の始まり。
      <SPAN id="inner"> 内側の内容。</SPAN>
      外側の内容の終わり。</SPAN>
      本文の内容の終わり。
    </P>
  </BODY>
</HTML>

このドキュメントでは、次のルールを想定しています:


body { display: block; font-size:12px; line-height: 200%; 
       width: 400px; height: 400px }
p    { display: block }
span { display: inline }

生成されたouterinner要素のボックスの最終位置は、各例で異なります。各図では、図の左側にある数字は、二重間隔(分かりやすくするため)の行の通常のフロー位置を示しています。

注意。このセクションの図は説明を目的としており、スケールに忠実ではありません。これらはCSS 2.2のさまざまなポジショニングスキームの違いを強調することを目的としており、例として提示されたレンダリングの参照を意図しているわけではありません。

9.8.1 通常のフロー

通常のフローを変更しないouterinnerに対する次のCSS宣言を考えます:


#outer { color: red }
#inner { color: blue }

P要素はすべてのインラインコンテンツ(匿名のインラインテキストと2つのSPAN要素)を含みます。そのため、すべてのコンテンツはP要素によって確立された包含ブロック内でインラインフォーマットコンテキストでレイアウトされ、次のようになります:

親ボックスと兄弟ボックス間のテキストの通常の流れを示す画像。   [D]

9.8.2 相対配置

相対配置の効果を見るために、次を指定します:


#outer { position: relative; top: -12px; color: red }
#inner { position: relative; top: 12px; color: blue }

テキストはouter要素まで通常どおりに流れます。outerテキストはライン1の終わりで通常のフローの位置と寸法に流れ込みます。その後、テキストを含むインラインボックス(3行に分配される)がユニットとして「-12px」(上方向)にシフトされます。

innerの内容はouterの子要素として、通常は「外側の内容の終わり」の直後(ライン1.5)にフローします。しかし、innerの内容自体がouterの内容に対して「12px」下方向にオフセットされ、ライン2の元の位置に戻ります。

outerの相対配置によって、outerに続くコンテンツが影響を受けないことに注意してください。

ボックスの内容に対する相対配置の効果を示す画像。   [D]

また、outerのオフセットが「-24px」であった場合、outerのテキストと本文のテキストが重なったであろうことにも注意してください。

9.8.3 ボックスのフロート

次に、次のルールを使用してinner要素のテキストを右にフロートさせた場合の効果を考えます:


#outer { color: red }
#inner { float: right; width: 130px; color: blue }

テキストはinnerボックスまで通常どおりに流れますが、innerボックスはフローから取り出され、右マージンにフロートされます(その『width』が明示的に指定されています)。フロートの左側の行ボックスが短縮され、ドキュメントの残りのテキストがそれらに流れ込みます。

ボックスをフロートさせた場合の効果を示す画像。   [D]

『clear』プロパティの効果を示すために、例にsibling要素を追加します:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>ポジショニングスキームの比較 II</TITLE>
  </HEAD>
  <BODY>
    <P>本文の内容の始まり。
      <SPAN id=outer> 外側の内容の始まり。
      <SPAN id=inner> 内側の内容。</SPAN>
      <SPAN id=sibling> 兄弟要素の内容。</SPAN>
      外側の内容の終わり。</SPAN>
      本文の内容の終わり。
    </P>
  </BODY>
</HTML>

次のルール:


#inner { float: right; width: 130px; color: blue }
#sibling { color: red }

は、innerボックスを以前と同様に右にフロートさせ、ドキュメントの残りのテキストを空いたスペースに流し込みます:

『clear』プロパティを設定せずにボックスをフロートさせた場合の効果を示す画像。   [D]

しかし、sibling要素の『clear』プロパティが『right』に設定されている場合(つまり、生成されたsiblingボックスが右側のフロートボックスの隣の位置を受け入れない場合)、siblingの内容はフロートの下で流れ始めます:


#inner { float: right; width: 130px; color: blue }
#sibling { clear: right; color: red }

『clear』プロパティを設定して要素をフロートさせた場合の効果を示す画像。   [D]

9.8.4 絶対配置

最後に、絶対配置の効果を考えます。 次のCSS宣言をouterinnerに適用します:


#outer { 
    position: absolute; 
    top: 200px; left: 200px; 
    width: 200px; 
    color: red;
}
#inner { color: blue }

これにより、outerボックスの上端がその包含ブロックに対して配置されます。位置指定されたボックスの包含ブロックは、最も近い位置指定された祖先(存在しない場合は初期包含ブロック)によって確立されます。この例では初期包含ブロックです。outerボックスの上側は包含ブロックの上端から「200px」下に、左側は左端から「200px」右に配置されます。outerの子ボックスは親ボックスに対して通常通りにフローします。

ボックスを絶対配置した場合の効果を示す画像。   [D]

次の例では、絶対配置されたボックスが相対配置されたボックスの子要素である場合を示しています。親のouterボックスが実際にはオフセットされていない場合でも、その『position』プロパティを『relative』に設定することで、そのボックスが位置指定された子孫の包含ブロックとして機能することができます。outerボックスは複数の行にまたがるインラインボックスであるため、最初のインラインボックスの上端と左端(以下の図で太い破線で示されています)が『top』および『left』のオフセットの基準として使用されます。


#outer { 
  position: relative; 
  color: red 
}
#inner { 
  position: absolute; 
  top: 200px; left: -100px; 
  height: 130px; width: 130px; 
  color: blue;
}

これにより、以下のような結果になります:

包含ブロックに対して絶対配置されたボックスの効果を示す画像。   [D]

outerボックスを位置指定しない場合:


#outer { color: red }
#inner {
  position: absolute; 
  top: 200px; left: -100px; 
  height: 130px; width: 130px; 
  color: blue;
}

innerの包含ブロックは初期包含ブロック(この例では)になります。以下の図は、この場合にinnerボックスが配置される場所を示しています。

通常配置された親によって確立された包含ブロックに対してボックスを絶対配置した場合の効果を示す画像。   [D]

相対配置と絶対配置を使用して変更バーを実装する方法を以下の例で示します。次の断片:


<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>

が次のような結果をもたらす可能性があります:

フロートを使用して変更バー効果を作成する方法を示す画像。   [D]

まず、段落(図でその包含ブロックの側面が示されています)が通常通りにフローされます。その後、包含ブロックの左端から「10px」オフセットされます(このオフセットを予測して右マージンが「10px」予約されています)。変更バーとして機能する2つのハイフンはフローから取り出され、現在の行に配置されます(『top: auto』のため)。包含ブロックの左端から「-1em」の位置に配置されます(最終位置にあるPによって確立された包含ブロック)。結果として、変更バーは現在の行の左側に「浮いている」ように見えます。

9.9 レイヤー構造のプレゼンテーション

9.9.1 スタックレベルの指定: 『z-index』 プロパティ

名前: z-index
値: auto | <integer> | inherit
初期値: auto
適用対象: 位置指定された要素
継承: no
パーセンテージ: N/A
メディア: ビジュアル
計算値: 指定された通り

位置指定されたボックスに対して、『z-index』 プロパティは以下を指定します:

  1. 現在のスタッキングコンテキストにおけるボックスのスタックレベル。
  2. ボックスがスタッキングコンテキストを確立するかどうか。

値の意味は以下の通りです:

<integer>
この整数は、現在のスタッキングコンテキスト内で生成されたボックスのスタックレベルです。このボックスは新しいスタッキングコンテキストも確立します。
auto
現在のスタッキングコンテキスト内で生成されたボックスのスタックレベルは0です。ボックスが『position: fixed』の場合、あるいはルート要素である場合も、新しいスタッキングコンテキストを確立します。

このセクションで「前面」とは、ユーザーが画面を正面から見たときにユーザーに近い位置を意味します。

CSS 2.2では、各ボックスは3次元空間内で位置を持ちます。水平および垂直方向の位置に加えて、ボックスは「z軸」に沿って配置され、互いに重なり合う形式で表現されます。z軸の位置は、ボックスが視覚的に重なる場合に特に重要です。このセクションでは、ボックスがz軸に沿ってどのように配置されるかを説明します。

レンダリングツリーがキャンバスに描画される順序は、スタッキングコンテキストに基づいて説明されます。スタッキングコンテキストはさらに別のスタッキングコンテキストを含むことができます。スタッキングコンテキストは、親スタッキングコンテキストの視点から見て原子的(他のスタッキングコンテキスト内のボックスがそのボックス間に入ることはない)です。

各ボックスは1つのスタッキングコンテキストに属します。特定のスタッキングコンテキスト内の位置指定された各ボックスには、整数のスタックレベルがあります。これは、同じスタッキングコンテキスト内の他のスタックレベルに対するz軸上の位置を示します。スタックレベルが大きいボックスは、スタックレベルが小さいボックスの前面に常に配置されます。ボックスは負のスタックレベルを持つこともできます。同じスタックレベルを持つボックスは、ドキュメントツリーの順序に従って背景から前面に向かって積み重ねられます。

ルート要素はルートスタッキングコンテキストを形成します。他のスタッキングコンテキストは、計算値が『z-index』以外の『auto』を持つ位置指定された要素(相対位置指定された要素を含む)によって生成されます。スタッキングコンテキストは包含ブロックとは必ずしも関連していません。CSSの将来のレベルでは、例えば『opacity』などの他のプロパティがスタッキングコンテキストを導入する可能性があります。

各スタッキングコンテキスト内では、次のレイヤーが背景から前面の順に描画されます:

  1. スタッキングコンテキストを形成する要素の背景とボーダー。
  2. 負のスタックレベルを持つ子スタッキングコンテキスト(最も負の値が先)。
  3. フロー内の非インラインレベルで位置指定されていない子孫要素。
  4. 位置指定されていないフロート。
  5. フロー内のインラインレベルで位置指定されていない子孫要素(インラインテーブルやインラインブロックを含む)。
  6. スタックレベルが0の子スタッキングコンテキストと位置指定された子孫要素。
  7. 正のスタックレベルを持つ子スタッキングコンテキスト(最も小さい正の値が先)。

各スタッキングコンテキスト内では、スタックレベル0の位置指定された要素(レイヤー 6)、位置指定されていないフロート(レイヤー 4)、インラインブロック(レイヤー 5)、インラインテーブル(レイヤー 5)は、それらの要素自体が新しいスタッキングコンテキストを生成したかのように描画されます。ただし、それらの位置指定された子孫要素や潜在的な子スタッキングコンテキストは現在のスタッキングコンテキストに参加します。

この描画順序は、各スタッキングコンテキストに対して再帰的に適用されます。このスタッキングコンテキストの描画順序の説明は、付録E.における詳細な規範的定義の概要を構成します。

次の例では、ボックス(「id」属性で名前付けされた)のスタックレベルは次の通りです: 「text2」=0、「image」=1、「text3」=2、「text1」=3です。「text2」のスタックレベルはルートボックスから継承されています。他のスタックレベルは『z-index』プロパティで指定されています。


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>Zオーダーの配置</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.png" alt="蝶の画像"
           style="z-index: 1">

    <DIV id="text1" class="pile" 
         style="z-index: 3">
      このテキストは蝶の画像の上に表示されます。
    </DIV>

    <DIV id="text2">
      このテキストはすべての下に表示されます。
    </DIV>

    <DIV id="text3" class="pile" 
         style="z-index: 2">
      このテキストはtext1の下にあるが、蝶の画像の上にあります。
    </DIV>
  </BODY>
</HTML>

この例は透明性の概念を示しています。背景のデフォルトの動作は、背後のボックスを可視化することです。この例では、それぞれのボックスが透明に下のボックスを重ねています。この動作は、既存の背景プロパティを使用して上書きすることができます。

9.10 テキストの方向: 『direction』 および『unicode-bidi』 プロパティ

適合するユーザーエージェントで双方向テキストをサポートしない場合、このセクションで説明する『direction』および『unicode-bidi』プロパティを無視できます。この例外には、システムのフォントに右から左に流れる文字が含まれているためにそれをレンダリングするが、右から左のテキスト方向の概念をサポートしないユーザーエージェントが含まれます。

特定のスクリプトの文字は右から左に書かれます。特にアラビア語やヘブライ語のスクリプトで書かれた文書や、混合言語のコンテキストでは、単一の(視覚的に表示された)ブロック内で混在した方向性を持つテキストが表示されることがあります。この現象は双方向性、略して「bidi」と呼ばれます。

Unicode標準([UNICODE][UAX9])は、テキストの適切な方向性を決定するための複雑なアルゴリズムを定義しています。このアルゴリズムは、文字のプロパティに基づいた暗黙の部分と、埋め込みや上書きのための明示的な制御から成り立っています。CSS 2.2はこのアルゴリズムに基づいて適切な双方向レンダリングを実現します。『direction』および『unicode-bidi』プロパティを使用すると、文書言語の要素と属性がこのアルゴリズムにどのようにマップされるかを指定できます。

双方向テキストをサポートするユーザーエージェントは、強制改行(bidi class B)やブロック境界によって中断されないすべてのインラインレベルのボックスのシーケンスにUnicode双方向アルゴリズムを適用する必要があります。このシーケンスは双方向アルゴリズムにおける「段落」単位を形成します。段落の埋め込みレベルは、UnicodeアルゴリズムのステップP2およびP3で示されるヒューリスティックではなく、包含ブロックの『direction』プロパティの値に従って設定されます。

テキストの方向性は文書言語の構造と意味に依存するため、これらのプロパティはほとんどの場合、文書型記述(DTDs)の設計者や特殊な文書の著者によってのみ使用されるべきです。デフォルトスタイルシートがこれらのプロパティを指定している場合、著者やユーザーはそれを上書きするルールを指定すべきではありません。

HTML 4仕様([HTML4], セクション8.2)はHTML要素の双方向性の挙動を定義しています。[HTML4]で指定された双方向性の挙動を達成するためのスタイルシートルールは、サンプルスタイルシートに示されています。また、HTML 4仕様には双方向性の問題に関する詳細情報が含まれています。

名前: direction
値: ltr | rtl | inherit
初期値: ltr
適用対象: すべての要素、ただし本文を参照
継承: yes
パーセンテージ: N/A
メディア: visual
計算値: 指定された通り

このプロパティは、ブロックの基本的な書字方向や、Unicode双方向アルゴリズムにおける埋め込みおよび上書きの方向(『unicode-bidi』を参照)を指定します。さらに、の列のレイアウト方向、水平オーバーフローの方向、'text-align: justify'の場合のブロック内の未完成の最終行の位置なども指定します。

このプロパティの値は以下の意味を持ちます:

ltr
左から右への方向。
rtl
右から左への方向。

『direction』プロパティがインライン要素の並べ替えに影響を与えるには、『unicode-bidi』プロパティの値が『embed』または『override』でなければなりません。

注意。 『direction』プロパティが表の列要素に指定された場合、列は文書ツリー内でセルの祖先ではないため、セルには継承されません。このため、CSSでは[HTML4]のセクション11.3.2.1で説明されている「dir」属性の継承ルールを簡単に取り込むことはできません。

名前: unicode-bidi
値: normal | embed | bidi-override | inherit
初期値: normal
適用対象: すべての要素、ただし本文を参照
継承: no
パーセンテージ: N/A
メディア: visual
計算値: 指定された通り

このプロパティの値は以下の意味を持ちます:

normal
要素は双方向アルゴリズムに関して追加の埋め込みレベルを開きません。インライン要素の場合、暗黙の並べ替えは要素の境界を超えて機能します。
embed
要素がインラインの場合、この値は双方向アルゴリズムに関して追加の埋め込みレベルを開きます。この埋め込みレベルの方向は『direction』プロパティによって指定されます。要素内では並べ替えは暗黙的に行われます。これは、要素の開始時にLRE(U+202A; 『direction: ltr』の場合)またはRLE(U+202B; 『direction: rtl』の場合)を追加し、要素の終了時にPDF(U+202C)を追加することに対応します。
bidi-override
インライン要素ではこれにより上書きが作成されます。 ブロックコンテナ要素では、別のブロックコンテナ要素内にないインラインレベルの子孫要素に対する上書きが作成されます。 これは、要素内では並べ替えが『direction』プロパティに従って完全に順序通りに行われ、双方向アルゴリズムの暗黙の部分が無視されることを意味します。これは、要素の開始時または匿名の子ブロックボックスの開始時にLRO(U+202D; 『direction: ltr』の場合)またはRLO(U+202E; 『direction: rtl』の場合)を追加し、要素の終了時にPDF(U+202C)を追加することに対応します。

各ブロックコンテナ内の文字の最終的な順序は、上記のように双方向制御コードが追加され、マークアップが削除され、結果の文字列がプレーンテキストのUnicode双方向アルゴリズムの実装に渡され、スタイル付きテキストと同じ改行が生成される場合と同じです。 このプロセスでは、『display: inline』の置換要素は 中立文字として扱われます。ただし、その『unicode-bidi』プロパティが『normal』以外の値を持つ場合、それらは要素に指定された『direction』で強い文字として扱われます。 他のすべての原子的なインラインレベルボックスは常に中立文字として扱われます。

インラインボックスを一方向(完全に左から右または完全に右から左)に流すことができるようにするために、より多くのインラインボックス(匿名インラインボックスを含む)を作成する必要がある場合があり、一部のインラインボックスを分割して順序を変更してから流す必要がある場合もあります。

Unicodeアルゴリズムには埋め込みの制限が61レベルあるため、『unicode-bidi』を『normal』以外の値で使用しないよう注意する必要があります。特に、『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なので、スタイルシートが書字方向を設定します。以下はそのスタイルシートです:

/* 双方向テキスト用ルール */
HEBREW, HE-QUO  {direction: rtl; unicode-bidi: embed}
ENGLISH         {direction: ltr; unicode-bidi: embed} 

/* 表示用ルール */
HEBREW, ENGLISH, PAR  {display: block}
EMPH                  {font-weight: bold}

HEBREW要素は右から左の基本方向を持つブロックであり、 ENGLISH要素は左から右の基本方向を持つブロックです。PARは親から基本方向を継承するブロックです。 したがって、最初の2つのPARは右上から読み始められ、最後の3つは左上から読み始められます。 なお、HEBREWとENGLISHは明確にするために選ばれた要素名であり、一般的には要素名は言語に依存せず構造を伝えるべきです。

EMPH要素はインラインレベルであり、その『unicode-bidi』の値が『normal』(初期値)であるため、 テキストの順序には影響を与えません。一方、HE-QUO要素は埋め込みを作成します。

このテキストのフォーマットは、行の長さが長い場合次のように見えるかもしれません:

               5WERBEH 4WERBEH english3 2WERBEH 1WERBEH

                                8WERBEH 7WERBEH 6WERBEH

english9 english10 english11 13WERBEH 12WERBEH

english14 english15 english16

english17 20WERBEH english19 18WERBEH

HE-QUOの埋め込みにより、HEBREW18がenglish19の右側に配置されることに注意してください。

行を分割する必要がある場合、次のようになるかもしれません:

       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の前に読む必要があるため、english19の上の行に配置されます。 以前のフォーマットから長い行を単純に分割するだけではうまくいきませんでした。また、english19の最初の音節が前の行に収まる可能性があったとしても、 左から右の単語を右から左のコンテキストで、またはその逆でハイフネーションすることは通常抑制されます。 これは、行の途中にハイフンを表示する必要があることを避けるためです。