9.4 正常流(done) - acelan86/css GitHub Wiki

在正常流中的盒存在于一个格式上下文(formatting context)中,这个上下文可能是块上下文或者行内上下文,但不能两者都是。块级盒处于一个块格式化上下文(block formatting context)中。行内盒处于一个行内格式化上下文(inline formatting context)中。

Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. Block-level boxes participate in a block formatting context. Inline-level boxes participate in an inline formatting context.

9.4.1 块格式化上下文(block formatting context)

浮动,绝对定位元素,不是块盒的块容器(例如inline-blocks, table-cells和table-captions)和拥有除了“visible”以外值的“overflow”属性的块盒(除非当这个值被传播到视窗)会为它们的内容建立一个新的块格式化上下文。

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

在一个块格式化上下文中,盒从包含块顶部开始,在垂直方向一个接一个进行布局。两个相邻兄弟盒之间的垂直距离由“margin”决定。在块格式化上下文中紧邻的块级盒之间的垂直margin会折叠。

In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.

在一个块格式化上下文中,盒子的左外边缘和包含块的左边缘对齐(在从右到左的格式中,右边缘对齐)。对于浮动元素也是如此(尽管由于浮动,盒子的line boxes会收缩),除非这个盒子建立一个新的块格式化上下文(在这种情况下由于浮动元素的原因盒子可能会变得很窄)。

读者注:由于浮动的存在,line box的宽度会收缩见例子。除非这个盒子建立新的块格式化上下文:是指左侧浮动,紧随的div设置overflow:hidden,这个div实际宽度收缩。例子 ---by fedeoo

In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box's line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).

For information about page breaks in paged media, please consult the section on allowed page breaks.

9.4.2 行内格式化上下文(inline formatting context)

在一个行内格式化上下文中,盒从包含块的顶部开始,按水平方向一个接一个进行布局。水平方向的margin,borders和padding作用于这些盒之间。在垂直方向上,盒可以按照不同的方式对齐:底部,顶部对齐,或者按照他们内部的文本基线(baseline)等。包含这些对齐盒子的矩形区域称为line box(行盒)。

In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. The rectangular area that contains the boxes that form a line is called a line box.

line box的宽度取决于包含块和是否存在浮动。line box的高度取决于本章行高的计算中给出的规则。

The width of a line box is determined by a containing block and the presence of floats. The height of a line box is determined by the rules given in the section on line height calculations.

一个line box总是足够高以包含它内部的所有盒。甚至可能高于它包含的盒中最高的那个(这些盒子会被对齐,使得它们的文本基线排成一条线)。当一个盒B的高度小于包含它的line box的高度时,B在这个line box中的垂直方向对齐方式取决于“vertical-align”属性(需要试下是B的vertical-align还是B.parentNode的)。当几个行内级盒无法在一个line box中水平放置的时候(行内盒太宽),它们被分到两个或者更多的垂直堆叠(vertically-stacked)的line box。也就是说,一个段落是line box的一个垂直栈(vertical stack)。line box被紧密的堆叠(除非特别声明)但永远不会重叠。

读者注: line box可能高于最高的那个box例子 ---by fedeoo

A line box is always tall enough for all of the boxes it contains. However, it may be taller than the tallest box it contains (if, for example, boxes are aligned so that baselines line up). When the height of a box B is less than the height of the line box containing it, the vertical alignment of B within the line box is determined by the 'vertical-align' property. When several inline-level boxes cannot fit horizontally within a single line box, they are distributed among two or more vertically-stacked line boxes. Thus, a paragraph is a vertical stack of line boxes. Line boxes are stacked with no vertical separation (except as specified elsewhere) and they never overlap.

一般来说,一个line box的左边缘和它的包含块的左边缘对齐而且它的右边缘和包含块的右边缘对齐(line box和包含块等宽)。但是,浮动的盒会在包含盒的边缘和line box的边缘之间(比如左浮,包含盒左- 浮动左 - 浮动右 - linebox左 - linebox右 - 包含盒右,这个意思)。也就是说,虽然在一个相同行内格式化上下文中的line box普遍拥有相同的宽度(包含盒的宽度),但是由于浮动元素导致水平方向的可用空间的减少,它们可能在宽度方面有差异。在同一个行内格式化上下文中的line box普遍在高度上面有差异(例如,当其他h只line-box只包含文本而其中有一个line-box包含了一个具有高度的图片)。

In general, the left edge of a line box touches the left edge of its containing block and the right edge touches the right edge of its containing block. However, floating boxes may come between the containing block edge and the line box edge. Thus, although line boxes in the same inline formatting context generally have the same width (that of the containing block), they may vary in width if available horizontal space is reduced due to floats. Line boxes in the same inline formatting context generally vary in height (e.g., one line might contain a tall image while the others contain only text).

当在一行中的所有行内级盒的宽度和比包含他们的line box小时,它们在line box中的水平位置的分配方式取决于“text-align”属性。如果这个属性的值是“justify”,客户端会尽可能将拉伸行内盒中的单词和空白(但inline-table和inline-block盒不会)。

When the total width of the inline-level boxes on a line is less than the width of the line box containing them, their horizontal distribution within the line box is determined by the 'text-align' property. If that property has the value 'justify', the user agent may stretch spaces and words in inline boxes (but not inline-table and inline-block boxes) as well.

当一个行内盒超出一个line box的宽度,它被分割成多个盒并且这些盒被分配到多个line box中。如果一个行内盒无法被分割(例如,如果这个行内盒包含了一个字符,或者语言中规定的单词折断规则不允许它在行内盒中被折断,或者如果这个行内盒被一个white-space为nowrap的值所影响,或者是一个pre),那么行内盒会溢出line box。

When an inline box exceeds the width of a line box, it is split into several boxes and these boxes are distributed across several line boxes. If an inline box cannot be split (e.g., if the inline box contains a single character, or language specific word breaking rules disallow a break within the inline box, or if the inline box is affected by a white-space value of nowrap or pre), then the inline box overflows the line box.

当一个行内盒被分割开,margins,borders和padding在分割发生的地方被忽略(没有视觉效果)。

When an inline box is split, margins, borders, and padding have no visual effect where the split occurs (or at any split, when there are several).

由于双向文本处理方式(bidirectional text processing),相同line box中的行内盒也可能被分割成多个盒。

Inline boxes may also be split into several boxes within the same line box due to bidirectional text processing.

line box被按需创建用于保持行内级内容在一个行内格式化上下文中。不包含“文本”,“加工过的空白”,“非0 margin”, “borders”和“其他流内内容”(如图片,inline-block元素或者inline table),还有不是已一个加工过的新行结尾的line box,在用于决定它们内部元素的位置的时候作为一个0高度的line box处理,在用作其他目的的时候当作不存在处理。

Line boxes are created as needed to hold inline-level content within an inline formatting context. Line boxes that contain no text, no preserved white space, no inline elements with non-zero margins, padding, or borders, and no other in-flow content (such as images, inline blocks or inline tables), and do not end with a preserved newline must be treated as zero-height line boxes for the purposes of determining the positions of any elements inside of them, and must be treated as not existing for any other purpose.

这里有一个解释行内盒的例子。下面段落(通过HTML块级元素P创建)包含了匿名文本分散在EM元素和STRONG元素之间。

Here is an example of inline box construction. The following paragraph (created by the HTML block-level element P) contains anonymous text interspersed with the elements EM and STRONG:

<p>several <em>emphasized words</em> appear 
<strong>in this</strong> sentence, dear.</p>

p元素生成一个块盒包含了5个行内盒,三个时匿名的:

  • 匿名的:“several”
  • EM:“emphasized words”
  • 匿名的:“appear”
  • STRONG:“in this”
  • 匿名的:“sentence,dear”

The P element generates a block box that contains five inline boxes, three of which are anonymous:

  • Anonymous: "Several"
  • EM: "emphasized words"
  • Anonymous: "appear"
  • STRONG: "in this"
  • Anonymous: "sentence, dear."

格式化这个段落时,客户端将这5个盒子依次放置在line box中。在这个例子中,P元素为line box建立一个包含块。如果这个包含块足够宽,所有的行内盒将放置在一个line box中。像下面这样:

To format the paragraph, the user agent flows the five boxes into line boxes. In this example, the box generated for the P element establishes the containing block for the line boxes. If the containing block is sufficiently wide, all the inline boxes will fit into a single line box:

如果不是,行内盒将被分割并分发到多个line box中。之前的那个段落可能会被分成下面这样:

If not, the inline boxes will be split up and distributed across several line boxes. The previous paragraph might be split as follows:

或者这样

or like this:

在上面这个例子中,EM盒子被分割成两个EM盒子(称作“split1”和“split2”).在split1之后和split2之前的margins,borders,padding,或者text-decorations不可见。

In the previous example, the EM box was split into two EM boxes (call them "split1" and "split2"). Margins, borders, padding, or text decorations have no visible effect after split1 or before split2.

考虑下面的例子:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//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的宽度,盒子将按照下面的方式分配:

Depending on the width of the P, the boxes may be distributed as follows:

匿名行内盒 D

  • margin被插入在“emphasized”的前面和“words”的后面。
  • padding被插入在“emphasized”的前面,上面,下面和“words”的后面,上面和下面。虚线被渲染在每一分割盒的三边上。
  • The margin is inserted before "emphasized" and after "words".
  • The padding is inserted before, above, and below "emphasized" and after, above, and below "words". A dashed border is rendered on three sides in each case.

译注:见example3.html,缩小浏览器窗口大小再看看?

9.4.3 相对定位

当一个盒子根据正常流或者浮动布局的时候,它的位置可以相对于这个位置被改变。称为相对定位。用下面的方法偏移一个盒子(B1)时,对盒子(B2)没有影响: B2被赋予一个在B1没有偏移时的那个位置,并且B2在B1的偏移量应用之后没有被重新定位。这表明相对定位可能导致盒子重叠。尽管如此,如果相对定位造成一个“overflow:auto”或者“overflow:scroll”的盒子溢出,客户端代理必须允许用户访问这个内容(在它的偏移位置),也就是,通过创建滚动条,这也许会影响布局。

Once a box has been laid out according to the normal flow or floated, it may be shifted relative to this position. This is called relative positioning. Offsetting a box (B1) in this way has no effect on the box (B2) that follows: B2 is given a position as if B1 were not offset and B2 is not re-positioned after B1's offset is applied. This implies that relative positioning may cause boxes to overlap. However, if relative positioning causes an 'overflow:auto' or 'overflow:scroll' box to have overflow, the UA must allow the user to access this content (at its offset position), which, through the creation of scrollbars, may affect layout.

相对定位的盒子保持他的正常流的大小,包括为它保留的原始断行和空白。包含块这个章节说明了何时一个相对定位盒子会建立一个新的包含块。

A relatively positioned box keeps its normal flow size, including line breaks and the space originally reserved for it. The section on containing blocks explains when a relatively positioned box establishes a new containing block.

对于相对定位的元素,“left”和“right”水平移动盒子,而不改变他们的大小。“left”将盒子往右移动而“right”将它们往左移动。由于盒子不会因为“left”和“right”属性而拉伸或者分割,因此使用值永远是:left=-right。

译注:对于相对定位元素,因为left,right属性不会影响他们的盒子的大小,所以left:10px和right:-10px的效果一样

For relatively positioned elements, 'left' and 'right' move the box(es) horizontally, without changing their size. 'Left' moves the boxes to the right, and 'right' moves them to the left. Since boxes are not split or stretched as a result of 'left' or 'right', the used values are always: left = -right.

如果“left”和“right”的值都是“auto”(它们的默认值),使用的值是“0”(就是,盒子保持在它原有的位置)。

If both 'left' and 'right' are 'auto' (their initial values), the used values are '0' (i.e., the boxes stay in their original position).

如果“left”是“auto”,它使用的值是“right”的负数(就是,盒子移动到左边“right”的值的地方)。

If 'left' is 'auto', its used value is minus the value of 'right' (i.e., the boxes move to the left by the value of 'right').

如果“right”是“auto”,它使用的值是“left”的负数。

If 'right' is specified as 'auto', its used value is minus the value of 'left'.

如果“left”和“right”的值都不是“auto”,位置超出约束,而它们中的某一个会被忽略。如果包含块的“direction”属性值是“ltr”,“left”的值优先使用而“right”的值将变成负的“left”的值。如果包含块的“direction”属性值是“rtl”,“right”的值优先使用而“left”的值被忽略。

If neither 'left' nor 'right' is 'auto', the position is over-constrained, and one of them has to be ignored. If the 'direction' property of the containing block is 'ltr', the value of 'left' wins and 'right' becomes -'left'. If 'direction' of the containing block is 'rtl', 'right' wins and 'left' is ignored.

例子。下面的三个规则是等价的:

Example. The following three rules are equivalent:

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”的值的负数)。

The 'top' and 'bottom' properties move relatively positioned element(s) up or down without changing their size. 'Top' moves the boxes down, and 'bottom' moves them up. Since boxes are not split or stretched as a result of 'top' or 'bottom', the used values are always: top = -bottom. If both are 'auto', their used values are both '0'. If one of them is 'auto', it becomes the negative of the other. If neither is 'auto', 'bottom' is ignored (i.e., the used value of 'bottom' will be minus the value of 'top').

注意:在脚本环境中,相对定位盒子的动态移动能产生动画效果 (见“visibility”属性)。相对定位可以用来产生上标和下标的效果, 行高并不会根据位置自动调整。更多信息可以查看行高的计算。

Note. Dynamic movement of relatively positioned boxes can produce animation effects in scripting environments (see also the 'visibility' property). Although relative positioning may be used as a form of superscripting and subscripting, the line height is not automatically adjusted to take the positioning into consideration. See the description of line height calculations for more information.

相对定位的例子在本章正常流,浮动和绝对定位的比较中提供。

Examples of relative positioning are provided in the section comparing normal flow, floats, and absolute positioning.


BFC的特点:

  • 盒子从包含块顶部开始一个接一个地垂直放置
  • 两个兄弟框之间的垂直距离取决于margin
  • 相邻的块级元素的垂直外边距会折叠
  • 块格式化上下文可嵌套

为内容生成新的块格式化上下文的条件:

  • 浮动元素
  • 绝对定位元素
  • 根元素
  • 行内块元素
  • 单元格
  • 表格标题元素
  • overflow属性值为非visible的元素

IFC的特点

  • 行内盒子从顶部开始,在水平方向上一个接一个放置(取决于ltr或者rtl)
  • 处于同一行的行内盒构成的矩形框称为行盒,行盒足够高以容纳行内所有的行内盒,且可能比所有盒子都高
  • 行盒内盒子的垂直对齐方式有vertical-align决定,水平方向对齐方式由text-align决定
  • 如果一个行盒内无法容纳所有内容,行内盒将被切分成多个行内盒,分布在多个行盒中,形成一个行盒的堆叠,每个行盒是紧密排列的。
  • 规范中不能被拆分的元素会溢出行盒而不被切割
⚠️ **GitHub.com Fallback** ⚠️