CSS の視覚整形モデル (visual formatting model) は、文書を処理して視覚メディアへ表示するアルゴリズムです。このモデルは CSS の基本概念です。

視覚整形モデルは、文書のそれぞれの要素を変換して、 CSS ボックスモデルに従った0、1、または数個のボックスを生成します。それぞれのボックスの配置は、以下のように定義されています。

  • ボックスの寸法: 詳細な定義、制約あり、制約なし
  • ボックスの種類: インライン、インラインレベル、不可分なインラインレベル、ブロック
  • 位置決定方法: 通常フロー、浮動、絶対位置指定
  • 文書ツリー内の他の要素: 子要素や隣接要素
  • ビューポートの大きさや位置
  • 含まれる画像の持つ固有の大きさ
  • その他外部からの情報

このモデルでは、ボックスはその包含ブロックの辺を基準に描かれます。通常、ボックスはその子孫要素のために包含ブロックを作ります。しかし、ボックスは包含ブロック内に制約されるわけではありません。ボックスの配置が包含ブロックの外側にはみ出る状態を、オーバーフローと言います。

ボックスの生成

ボックスの生成は CSS の視覚整形モデルの一部で、文書内の要素からボックスを作ることです。生成されたボックスはそれぞれ別個の種類を持ち、視覚整形モデルで行うことが変わります。生成されるボックスの種類は CSS の display プロパティによって決まります。

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

CSS の display プロパティの計算値が block, list-item, table のいずれかであるとき、要素はブロックレベルであると言います。ブロックレベル要素はブロックとして視覚整形され (例:段落)、縦方向に積み重ねられます。

ブロックレベルボックス (block-level box) は、ブロック整形コンテキストに関わるボックスです。ブロックレベル要素はそれぞれ、主ブロックレベルボックス (principal block-level box) と呼ばれる、少なくとも1つのブロックレベルボックスを生成します。リスト項目要素のように、項目先頭の黒丸や他の文字要素用にさらにボックスを生成するものもあります。しかし、ほとんどは主ブロックレベルボックスだけを生成します。

主ブロックレベルボックスは、子孫が作成したボックスや生成されたコンテンツを含みます。ボックスは配置体系に従うボックスでもあります。

venn_blocks.pngブロックレベルボックスは、ブロックコンテナーボックス (block container box) にもなり得ます。ブロックコンテナーボックスには、他のブロックレベルボックスだけを含むものと、インライン整形コンテキストを作るインラインボックスだけを含むものがあります。

ブロックレベルボックスとブロックコンテナーボックスが別々の概念を表すことに留意して下さい。前者は、ボックスが、その外部 (親要素や兄弟要素) に対しどのようにふるまうかについてを述べる概念であり、後者は、ボックスが、その内部 (子孫要素) とどのように相互作用するかについてを述べる概念です。ブロックレベルボックスには、表 (テーブル) のように、ブロックコンテナーボックスではないものがあります。また、逆に一部のブロックコンテナーボックスには、非置換インラインブロックや非置換の表のセルのように、ブロックレベルボックスではないものがあります。

ブロックコンテナーボックスでもあるブロックレベルボックスを、ブロックボックスと呼びます。

無名ブロックボックス

視覚整形アルゴリズムが、補助用のボックスを必要とする場合があります。これらのボックスを 無名ボックス (anonymous boxes) と呼んでいます。

セレクターは無名ボックスに対して働かないので、スタイルシートからスタイルを適用することができません。継承可能な CSS プロパティはすべて inherit 値を持ち、継承不能な CSS プロパティはすべて initial 値を持つことになります。

ブロックコンテナーボックスには、インラインレベルボックスのみか、ブロックレベルボックスのみを入れられます。しかし文書は両方を含んでいることがよくあります。この場合、隣接するインラインレベルボックスを囲むように無名ブロックボックスが作られます。

次の HTML コードを見てみましょう (既定のスタイルシートが適用されており、 <div><p> 要素にはdisplay: block が適用されています)。

<div>Some inline text <p>followed by a paragraph</p> followed by more inline text.</div>

2つの無名ブロックボックスが作られます。1つは p 要素の前にあるテキスト (Some inline text) 用で、もう1つは p 要素の後ろのテキスト (followed by more inline text) 用です。こうして次のブロック構造ができます。

anonymous_block-level_boxes.png

表示結果は次のとおりです。

Some inline text
followed by a paragraph
followed by more inline text.

<p> 要素のボックスと違って、ウェブ制作者はこの2つの無名ボックスのスタイルを制御できません。継承可能なプロパティについては <div> のプロパティ値から値が取られます。例えばテキストの色を定義する color は継承されます。それ以外のプロパティは initial 値に設定されます。例えば background-color は定義されておらず、このプロパティの initial 値である透明になります。したがって <div> の背景を透かして見ることができます。一方で、<p> ボックスには背景色を指定できます。同様に、2つの無名ボックスはそのテキストに、常に同じ色を使おうとします。

無名ブロックボックスが作られるもう一つの場合は、インラインボックスが、1つまたは複数のブロックボックスを含む場合です。この場合、ブロックボックスを含むボックスは2つのインラインボックスに分けられ、ブロックボックスの前後に1つずつ置かれます。ブロックボックスより前にあるインラインボックスはすべて無名ブロックボックスに入れられます。ブロックボックスの後ろにあるものも同様です。この結果ブロックボックスは、インライン要素を含む2つの無名ブロックボックスの、兄弟要素になります。

もしブロックボックスが複数あれば、その間にインラインコンテンツがなくても、一群のボックスの前後に無名ブロックボックスが作られます。

次の HTML コードのように、 <p> には display:inline を、 <span> には display:block を適用すると、以下のようになります。

<p>Some <em>inline</em> text <span>followed by a paragraph</span> followed by more inline text.</p>

2つの無名ボックスが作成され、1つは span 要素の前の文字列 (Some inline text)、もう1つは span 要素の後の文字列 (followed by more inline text) で、以下のようなブロック構造を構築します。

結果は以下のようになります。

Some inline text
followed by a paragraph
followed by more inline text.

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

CSS の display プロパティの計算値が inlineinline-blockinline-table のいずれかであるとき、その要素はインラインレベルであると言います。外見的には、コンテンツのブロックを構成していませんが、他のインラインレベルのコンテンツといっしょに行内に配置されます。インラインレベル要素の典型例は、段落のコンテンツ、強調表示のような書式つきのテキスト、または画像です。

venn_inlines.png

この図は古い用語を使用しています。以下のメモを参照してください。その上、 CSS 2.2 の仕様書、 chapter 9.2.2 では「インラインレベル要素は、インライン整形コンテキストに加わるインラインレベルボックスを生成する」と定義されており、右側の黄色い楕円は、定義上、左側のものと同じか、それよりも大きい (数学的な上位集合) ので、この図は誤っています。

インラインレベル要素は、インラインレベルボックスを作ります。これは、インライン整形コンテキストに加わるために、ボックスとして定義されたものです。インラインボックス とは、インラインレベルボックスでもあり、それらのコンテナーのインライン整形コンテキストに加わるボックスでもあります。例えば display:inline である非置換ボックスはすべてこれに該当します。インライン整形コンテキストに加わらないインラインレベルボックスを、不可分のインラインレベルボックスと言います。これは、置換インラインレベル要素か、 display の計算値が inline-block または inline-table である要素によって生成されます。不可分のインラインレベルボックスは、インラインボックスと違い、ボックスに分けられません。

メモ: 不可分のインラインレベルボックス (atomic inline-level boxes) は始め、 不可分のインラインボックス と呼ばれていましたが、実際にはインラインボックスではないので、不適切でした。その後、これは仕様書の正誤表で訂正されました。とは言え、名前が変更されただけなので、文献に登場する不可分のインラインボックスと、不可分のインラインレベルボックスは読み誤りやすくなっています。
不可分のインラインボックスは、インライン整形コンテキスト内で複数の行にわけることができません。
<style>
  span {
    display:inline; /* 既定値 */
  }
</style>
<div style="width:20em;">
   The text in the span <span>can be split in several
   lines as it</span> is an inline box.
</div>

結果は以下の通りです。

The text in the span can be split into several lines as it is an inline box.
<style>
  span {
    display:inline-block;
  }
</style>
<div style="width:20em;">
   The text in the span <span>cannot be split in several
   lines as it</span> is an inline-block box.
</div>

結果は以下の通りです。

The text in the span cannot be split into several lines as it is an inline-block box.

無名インラインボックス

ブロックボックスのように、 CSS エンジンによって自動的にインラインボックスが作られるケースがいくつかあります。このインラインボックスは無名で、セレクターで指定できません。無名インラインボックスのプロパティは、継承可能なものは継承された値を、それ以外は initial 値を持ちます。

無名のインラインボックスが作られるよくあるケースは、インライン整形コンテキストを作るブロックボックス直下の子要素としてテキストがある場合です。この場合、テキストは可能な限り大きな無名インラインボックスに入れられます。また、最終的に CSS の white-space プロパティで指定された動作で取り除かれる空白のコンテンツは、空になるので無名インラインボックスを生成しません。

Example TBD

その他の種類のボックス

行ボックス (line boxes)

行ボックスは、インライン整形コンテキストにおいて、行を表現するために生成されるボックスです。行ボックスは、包含するブロックボックスの境界から反対側の境界まで広がります。フロートがあれば、行ボックスは左側のフロートの一番右のボーダーから始まり、右側のフロートの一番左のボーダーで終わります。

このボックスは技術的なもので、通常はウェブ製作者が頭を悩ます必要はありません。

ランインボックス (run-in boxes)

ランインボックスdisplay:run-in で定義されるもので、次に来るボックスのタイプによってブロックボックスもしくはインラインボックスになります。これは、可能なときは最初の段落の内部にタイトルが入り込む (同行見出し) ようにさせたいときに使えます。

メモ: ランインボックスは、相互運用可能に実装できるほど十分な仕様に至らなかったため、CSS 2.1 標準から取り除かれました。ランインボックスは CSS 3 で復活する可能性はありますが、それまでは試験的機能と見なされています。制作に使うべきではありません。

モデル起因のボックス (model-induced boxes)

CSS では、インライン整形コンテキストやブロック整形コンテキストの他にも、要素に適用できるコンテンツモデルがあります。これらの追加のモデルは、特定のレイアウト定義に使われ、次のような種類のボックスを定義することもあります。

  • 表コンテンツモデル表ラッパーボックス表ボックスのみならず、キャプションボックスなどのより特化されたボックスも作ることがあります。
  • 段組みコンテンツモデルはコンテナーボックスとコンテンツの間に段ボックス を作ることがあります。
  • 試験的な機能である、グリッドやフレックスボックスによるコンテンツモデルも、別の種類のボックス (別の仕組みで中身をレイアウトするボックス) を作ります。

配置スキーム (positioning schemes)

ボックスが生成されたなら、 CSS エンジンは それらのレイアウト上での位置を決める必要があります。そのためには、次のアルゴリズムのいずれかを使います:

  • 通常フロー。それぞれのボックスを他のボックスの後に並べます。
  • フロート アルゴリズム。通常フローからボックスを引き抜いて、それを包含しているボックスの側方に置きます。
  • 絶対位置指定。ボックスは、それを包含している要素が確立する座標系の中で、絶対的な位置にされます。絶対位置にされた要素は、他の要素と重なり合い得るようになります。

通常フロー

通常フロー においては、ボックスは他のボックスの後に配置されます。ブロック整形コンテキストの下では、垂直に並べられます。インライン整形コンテキストの下では、水平に並べられます。 positionstatic または relative に設定されていて、 floatnone に設定されている場合、通常フローになります。

通常フローのブロック整形コンテキスト内では、ボックスは他のボックスの後に垂直に配置されます。

インライン整形コンテキスト内では、通常フローでは、ボックスは他のボックスの後に水平に配置されます。

通常フローは、更に、静的位置指定と相対的位置指定の2つに分かれます。

  • 静的位置指定 (static positioning)は、position プロパティに static 値が設定されたもので、通常フローによるレイアウトで定義された位置にそのまま、ボックスが描画されます。
  • 相対位置指定 (relative positioning) は、position プロパティに relative が設定されたもので、topbottomleftright の CSS プロパティで定義された移動量を使ってボックスが描かれます

フロート

フロート位置決定スキームでは、フローティングボックス、または単にフロートと呼ばれるボックスが、現在行の始めか終わりに置かれます。この結果、clear CSS プロパティが指定されない限りは、通常フローに含まれるテキストやその他のボックスが、フロートの周りを沿うように流し込まれます。

フロート位置決定スキームは、positionstatic または relative であるときに、floatnone 以外に設定すると選べます。floatleft に設定されると、フロートは行ボックスの始めに置かれ、それを縮めます。right に設定されれば、フロートは行ボックスの最後に置かれ、それを縮めます。

絶対位置指定

絶対位置決定スキーム では、ボックスは通常フローから完全に外され、通常フローの要素と相互作用しません。包含ブロックを基準に、 topbottomleftright の CSS プロパティを使って位置が決定されます。

positionabsolute または fixed である要素は、絶対位置で位置が決められます。

固定位置指定要素 (fixed positioned element) は、包含ブロックがビューポートである絶対位置指定要素です。スクロールしてもビューポートは動かないので、この要素もスクリーンに固定されます。

関連項目

ドキュメントのタグと貢献者

このページの貢献者: mfuji09, SphinxKnight, uint256_t, mokeke, ethertank, sosleepy
最終更新者: mfuji09,