文章目录
  1. 1. 标准中的描述
    1. 1.1. Block-level elements and block boxes
    2. 1.2. Block formatting contexts
  2. 2. 总结/需要注意的
    1. 2.1. Block formatting contexts
      1. 2.1.1. What triggers block formatting contexts
      2. 2.1.2. How block formatting contexts flow
      3. 2.1.3. What block formatting contexts do
    2. 2.2. block-level boxes
      1. 2.2.1. relationship with block formatting contexts
    3. 2.3. containing block

在知乎看到这样一个问题“CSS 中 block-level boxes、containing block、block formatting context 三者之间的区别和联系是怎样的?”
我傻傻分不清楚 = =,这必须记录一下这些概念加深印象,备个忘,同时也让自己掰扯掰扯这些概念。
(以下标准翻译部分是博主自己尝试翻译的 >_< ,如有错误或不到位的请指正)


标准中的描述

Block-level elements and block boxes

9.2.1 Block-level elements and block boxes

Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the ‘display’ property make an element block-level: ‘block’, ‘list-item’, and ‘table’.

Block-level boxes are boxes that participate in a block formatting context. Each block-level element generates a principal block-level box that contains descendant boxes and generated content and is also the box involved in any positioning scheme. Some block-level elements may generate additional boxes in addition to the principal box: ‘list-item’ elements. These additional boxes are placed with respect to the principal box.

Except for table boxes, which are described in a later chapter, and replaced elements, a block-level box is also a block container box. A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes. Not all block container boxes are block-level boxes: non-replaced inline blocks and non-replaced table cells are block containers but not block-level boxes. Block-level boxes that are also block containers are called block boxes.

The three terms “block-level box,” “block container box,” and “block box” are sometimes abbreviated as “block” where unambiguous.

译:

块级元素(block-level elements)是源文档中那些以块的形式显示的一些元素(比如:段落(paragraphs))。以下”display”属性值,可以使一个元素 变成块级 : “block” , “list-item” 和 “table”

块级盒子(block-level boxes) 会参与到 块级格式化上下文(block formatting context)(一种布局方式) 。每个块级元素会生成一个首要块级盒子(principal block-level box) ,这个首要块级盒子包含后代盒子们,以及生成内容,并且这个块级元素也被包含到任何一种定位机制中。一些块级元素除了会生成首要块级盒子之外,还会生成额外盒子们,比如:”list-item” elment。这些额外的盒子参照首要块级盒子放置。

除了表格盒子(table boxes)(将在之后的章节中描述它)和可替换元素(replaced elements),一个块级盒子也是一个块容器盒子(block container box)。一个块容器盒子要么只包含块级盒子,要么创建一个只包含行级盒子(inline-level boxes)行内格式化上下文(inline formatting context)。不是所有块容器盒子都是块级盒子,比如:不可替换行内块(non-replaced inline blocks)不可替换表格单元格都是块容器盒子但不是块级盒子。是块级盒子又是块容器盒子的被叫做块盒子(block boxes)

这三个术语 “块级盒子(block-level boxes)“,”块容器盒子(block container box)“和”块盒子(block boxes)“在表述清晰的条件下有时被简称为”块(block)”。


Block formatting contexts

9.4.1 Block formatting contexts

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.

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.

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.

译:

不是块盒子(block boxes)的:浮动(floats)绝对定位元素(absolutely positioned elements)块容器(block containers)(如:行内块(inline-blocks)表格单元格(table-cells)表格标题(table-captions));以及有”overflow”属性,且”overflow”属性值不为”visible”的(除了当值传递到窗口 这句没懂…)都会为他们的内容创建一个新的块级格式化上下文(block formatting contexts)

在一个块级格式化上下文(block formatting contexts)中,盒子们自所在的 containing block 顶部起一个接一个垂直排列,水平方向上撑满整个宽度 (除非内部的盒子自己内部建立了新的 BFC)。在两个兄弟盒子之间的垂直间距被定义为”margin”属性。块级格式化上下文中毗邻的块级盒子(block-level boxes)之间的垂直方向边距不会发生折叠(collapse)。

在一个块级格式化上下文中,每个盒子左外边框紧挨着其包含块的左边框(从右向左排列时,右外边框紧挨着其包含块的右边框)。即使是浮动(floats)的情况下也成立(即使一个(父元素)盒子的线框会由于(子元素)浮动收缩),除非这个盒子创建了一个新的块级格式化上下文(在这种情况下这个盒子自己会由于浮动会变窄)。

想了解关于分页媒体(paged media)中的分页符(page breaks),请查阅这个章节:allowed page breaks


总结/需要注意的

Block formatting contexts

What triggers block formatting contexts

  • float 除了none以外的值
  • overflow 除了visible 以外的值(hidden,auto,scroll )
  • display (table-cell,table-caption,inline-block)
  • position(absolute,fixed)
  • fieldset元素

How block formatting contexts flow

block formatting contexts 属于普通流(normal flow)

What block formatting contexts do

  1. 创建了 BFC 的元素,不和它的子元素发生外边距折叠。

    外边距折叠的规则:仅当两个块级元素相邻并且在同一个块级格式化上下文时,它们垂直方向之间的外边距才会叠加。也就是说,即便两个块级元素相邻,但当它们不在同一个块级格式化上下文时它们的边距也不会折叠。因此,阻止外边距折叠只需产生新的 BFC 。

    DEMO:

    三个 div 各包含一个 p 元素,三个 div 及其包含的 p 元素都有顶部和底部的外边距,但只有第三个 div 的边距没有与它的子元素 p 的外边距折叠。这是因为第三个 div 创建了新的 BFC ,由此可见:创建了 BFC 的元素,不和它的子元素发生外边距折叠。

  2. BFC 可以包含浮动的元素,闭合浮动。

    这也正是使用 overflow: hidden 与 overflow: auto 方法闭合浮动的原理,使用 overflow: hidden 或 overflow: auto 触发浮动元素的父元素的 BFC 特性,从而可以包含浮动元素,闭合浮动。
    W3C 的原文是“’Auto’ heights for block formatting context roots”,也就是 BFC 会根据子元素的情况自动适应高度,即使其子元素中包括浮动元素。

    DEMO:

    更详细的清除浮动方法可见:浮动和它的工作原理?清除浮动的技巧?

  3. BFC 可以阻止元素被浮动元素覆盖

    浮动元素的块级兄弟元素会无视浮动元素的位置,尽量占满一整行,这样就会被浮动元素覆盖,为该兄弟元素触发 BFC 后可以阻止这种情况的发生。
    DEMO:
    块级元素会被它的兄弟浮动元素覆盖

    触发了 BFC 的元素不会被它的兄弟浮动元素覆盖

    子元素宽度均小于父元素,但父元素宽度不足以容纳一行中所有子元素时,非浮动子元素会下沉


block-level boxes

relationship with block formatting contexts

一个 block-level element (‘display’ 属性值为 ‘block’, ‘list-item’ 或是 ‘table’) 会生成一个 block-level box,
这样的盒子会参与到 block-formatting context (一种布局的方式) 中。


containing block

一般来说,盒子本身就为其子孙建立了 containing block,用来计算内部盒子的位置、大小,而对内部的盒子,具体采用哪个 containing block 来计算,需要分情况来讨论:

  1. 根元素所在的 containing block 被称为 initial containing block,在我们常用的浏览器环境下,指的是原点与 canvas 重合,大小和 viewport 相同的矩形;
  2. 对于 position 为 static 或 relative 的元素,其 containing block 为祖先元素中最近的 block container box 的 content box (除 margin, border, padding 外的区域);
  3. 对于 position:fixed 的元素,其 containing block 由 viewport 建立;
  4. 对于 position:absolute 的元素,则是先找到其祖先元素中最近的 position 属性非 static 的元素,然后判断:
    1. 若此元素为 inline 元素,则 containing block 为能够包含这个元素生成的第一个和最后一个 inline box 的 padding box (除 margin, border 外的区域) 的最小矩形;
    2. 否则则由这个祖先元素的 padding box 构成。
      如果都找不到,则为 initial containing block。

参考文献:
[1] 9.2.1 Block-level elements and block boxes
[2] 9.4.1 Block formatting contexts
[3] KB008: 包含块( Containing block )
[4] CSS 101: Block Formatting Contexts
[5] 详说 Block Formatting Contexts (块级格式化上下文)
[6] How does the CSS Block Formatting Context work?
[7] CSS 中 block-level boxes、containing block、block formatting context 三者之间的区别和联系是怎样的?

文章目录
  1. 1. 标准中的描述
    1. 1.1. Block-level elements and block boxes
    2. 1.2. Block formatting contexts
  2. 2. 总结/需要注意的
    1. 2.1. Block formatting contexts
      1. 2.1.1. What triggers block formatting contexts
      2. 2.1.2. How block formatting contexts flow
      3. 2.1.3. What block formatting contexts do
    2. 2.2. block-level boxes
      1. 2.2.1. relationship with block formatting contexts
    3. 2.3. containing block