Please note, this is a STATIC archive of website developer.mozilla.org from November 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

视觉格式化模型

CSS 视觉格式化模型(visual formatting model)是用来处理文档并将它显示在视觉媒体上的机制。这是 CSS 的一个基础概念。 视觉格式化模型根据 CSS 盒模型为文档的每个元素生成 0,1 或多个盒。每个盒的布局由如下内容组成:

  • 盒尺寸:明确指定,受限或没有指定
  • 盒类型:行内(inline), 行内级别(inline-level), 原子行内级别(atomic inline-level), 块(block)盒;
  • 定位方案(positioning scheme): 常规流,浮动或绝对定位;
  • 树中的其它元素: 它的子代与同代;
  • 视口(viewport) 尺寸与位置;
  • 内含图片的固定尺寸;
  • 其它信息。

一个盒相对于它的包含块(containing block) 的边界来渲染。通常盒为它的后代元素建立包含块。注意盒并不受它的包含块的限制,当它的布局跑到包含块的外面时称为溢出(overflow)

Note:  请查看规范对  包含块 containing block  的定义, 与 块容器盒(block container box) 概念不同。

盒的生成(Box generation)

CSS 视觉格式化模型的一部分工作是从文档元素生成盒。生成的盒拥有不同类型,并对视觉格式化模型的处理产生影响。生成盒的类型取决于 CSS 属性 display 

块级元素与块盒(Block-level elements and block boxes)

当元素的 CSS 属性  display 为 block, list-item 或 table 时,它是块级元素 block-level 。块级元素(比如<p>)视觉上呈现为块,竖直排列。

块级盒参与(块格式化上下文 block formatting context)。每个块级元素至少生成一个块级盒,称为主要块级盒(principal block-level box)。一些元素,比如<li>,生成额外的盒来放置项目符号,不过多数元素只生成一个主要块级盒。 

主要块级盒将包含后代元素生成的盒以及生成的内容。它也是可以使用(定位方案 positioning scheme)的盒。

venn_blocks.png一个块级盒可能也是一个块容器盒。块容器盒(block container box) 只包含其它块级盒,或生成一个行内格式化上下文(inline formatting context),由此只包含行内盒。注意块级盒与块容器盒概念不同。 前者描述元素跟它的父元素与兄弟元素之间的表现,后者描述元素跟它的后代之间的影响。有些块级盒,比如表格,不是块容器盒。相反,一些块容器盒,比如非替换行内块及非替换表格单元格,不是块级盒。

同时是块容器盒的块级盒称为块盒(block boxes)。(译注:块级盒与块盒名字相近,注意分别^-^)

匿名块盒(Anonymous block boxes)

有时需要添加补充性盒,这些盒称为匿名盒(anonymous boxes),  它们没有名字,不能被 CSS 选择符选中。

不能被 CSS 选择符选中意味着不能用样式表添加样式。这意味着所有继承的 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>
将创建两个匿名块盒,一个包含 <p> 前面的文本 (Some inline text), 一个包含 <p> 后面的文本(followed by more inline text),  结构如下:

anonymous_block-level_boxes.png

结果:

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

<p> 元素不同, 开发者不能控制这两个匿名盒。对于可继承属性, 它们将取 <div> 的属性值, 比如 color。对于非继承属性,值为初始值 ,比如没有指定 background-color, 值为初始值即 transparent,于是 <div> 背景可见。而 <p> 可以指定 background-color 。类似的,这两个匿名盒文本是一样的颜色。

另一种将创建匿名块盒的情况是,一个行内盒包含了一个或几个块盒。在这种情况下,包含块盒的盒将拆分为两个行内盒放置于块盒前后,然后分别由两个匿名块盒包含。这样块盒就与两个包含行内元素的匿名块盒形成了兄弟关系。

如果行内包含多个块盒,并且这些块盒之间没有夹杂内容,将在这些块盒前后创建匿名块盒。

TBD: Describe example

行内级元素与行内盒(Inline-level elements and inline boxes)

当元素的 CSS 属性 display 的计算值为 inline, inline-block 或 inline-table 时,称它为行内级元素。视觉上它将内容与其它行内级元素排列为多行。典型的如段落内容,有文本(可以有多种格式譬如着重),或图片,都是行内级元素。

venn_inlines.png行内级元素生成行内级盒(inline-level boxes),参与行内格式化上下文(inline formatting context)。同时参与生成行内格式化上下文的行内级盒称为行内盒(Inline boxes)。所有display:inline 的非替换元素生成的盒是行内盒。而不参与生成行内格式化上下文的行内级盒称为原子行内级盒(atomic inline-level boxes)。这些盒由可替换行内元素,或 display 值为 inline-block 或 inline-table 的元素生成,不能拆分成多个盒。

注意:起初原子行内级盒(atomic inline-level boxes)被称为原子行内盒(atomic inline boxes)。很不幸,它们并非行内盒。规范的勘误表修正了这个错误。 不管怎样,当再看到原子行内盒时可以放心的当成原子行内级盒,因为只是改了名字。
原子行内盒在行内格式化上下文里不能分成多行。
<style>
  span {
    display:inline; /* default value*/
  }
</style>
<div style="width:20em;">
   span 里的文本 <span>可以
   分成多行因为</span>它是个行内盒。
</div>

结果:

span 里的文本可以
分成多行因为它是个
行内盒。
<style>
  span {
    display:inline-block;
  }
</style>
<div style="width:20em;">
   span 里的文本 <span>不能分成多行
   因为它</span> 是个行内块盒。
</div>

结果:

span 里的文本 
不能分成多行因为它
是个行内块盒。

匿名行内盒(Anonymous inline boxes)

类似于块盒,CSS 引擎有时自动生成行内盒。这些盒也是匿名的,因为它们没有对应的选择器名字。它们继承所有可继承的属性,非继承的属性取 initial。 

匿名行内盒最常见的例子是块盒直接包含文本,文本将包含在匿名行内盒中。空白如果使用white-space 去掉,则不会生成匿名行内盒。

Example TBD

其它类型盒

行盒(Line boxes)

行盒由行内格式化上下文(inline formatting context)产生的盒,用于表示一行。在块盒里面,行盒从块盒一边排版到另一边。 当有浮动时, 行盒从左浮动的最右边排版到右浮动的最左边。

行盒是技术上的实现,开发者通常不用操心它。

插入盒(Run-in boxes)

插入盒由  display:run-in 定义,由后续盒的类型决定是块盒还是行盒。可以用来在第一个段落中插入标题。

Note: 插入盒(Run-in boxes)从 CSS 2.1 标准中移除了,因为可操作的实现定义不足。 可能 CSS3 会引入,但是这是实验性质,不能用于生产环境。 

Model-induced boxes

除了行内及块格式化上下文, CSS 允许元素有更多的内容模型。这些增加的模型是为了描述特定的布局,可能会定义新的盒类型:

定位方案(Positioning schemes)

一旦盒生成了, CSS 引擎要指定它们的位置。会用到下列之一的方案:

  • 常规流(normal flow)盒一个接一个排列。
  • 浮动(floats)方案将盒从常规流里提出来,放在当前盒的旁边。
  • 绝对定位(absolute positioning)中的盒坐标是绝对的。绝对定位元素可以盖住使用其它定位方案的元素。

常规流(Normal flow)

在常规流中,盒一个接着一个排列。在块级格式化上下文里面, 它们竖着排列;在行内格式化上下文里面, 它们横着排列。 当 position 为 static 或 relative,并且 float 为 none 时会触发常规流。

在块级格式化上下文里面, 常规流竖着排列。

[image]

行内格式化上下文里面, 常规流横着排列。

[image]

常规流分为两种情况:

  • 对于静态定位(static positioning)position 值 为 static , 盒的位置是常规流布局里的位置。
    [image]
  • 对于相对定位(relative positioning),   position 值 为 relative, 盒偏移位置由这些属性定义 top, bottom, left and right 。即使有偏移,仍然保留原有的位置,其它常规流不能占用这个位置。

浮动(Floats)

对于浮动定位方案(float positioning scheme), 盒称为浮动盒(floating boxes)。它位于当前行的开头或末尾。这导致常规流环绕在它的周边,除非设置 clear 属性。

要使用浮动定位方案,元素 CSS 属性 position 为 static 或 relative,然后  float 不为 none 。如果 float 设为 left, 浮动由行盒的开头开始定位。如果设为 right, 浮动定位在行盒的末尾。

[image]

绝对定位(Absolute positioning)

对于绝对定位方案盒从常规流中被移除,不影响常规流的布局。 它的定位相对于它的包含块,相关CSS属性: top, bottom, leftright

如果元素的属性position为 absolute 或 fixed, 它是绝对定位元素。

固定定位元素(fixed positioned element)也是绝对定位元素,它的包含块是视口。当页面滚动时它固定在屏幕上,因为视口没有移动。

 

文档标签和贡献者

 此页面的贡献者: ziyunfei, zhanglun, teoli, sunnylost, yan
 最后编辑者: zhanglun,