CSS文档流

本文最后更新于 2025年8月2日 下午

文档

当浏览器解析 HTML 文档时,会在内存里将页面的所有元素表示为 DOM(文档对象模型)。它是一个树结构,其中每个元素都由一个节点表示。<html>元素是顶级根节点。它的下面是子节点:<head><body>。再下面是逐级嵌套的后代节点。

在文档中,根节点是所有其他元素的祖先节点。根节点有一个伪类选择器(:root)可以用来选中它自己。这等价于类型选择器 html,但是 :root 的优先级相当于一个类名,而不是一个标签。

定位方案是控制元素的布局,有三种常见方案:普通流、浮动、定位。

普通流

普通文档流指的是网页元素的默认布局行为。

普通文档流中,元素按照其在 HTML 文档中的先后位置至上而下布局。此过程中,行内元素水平排列,跟随文字的方向从左到右排列,直到当行被占满然后换行。块级元素则会被渲染成为一个完整的新行,它会占据完整的一行,前后都有换行。除非另外指定,否则所有元素默认都是普通流定位,即普通流中元素的位置由该元素在 HTML 文档中的位置决定。

普通文档流是为限定的宽度和无限的高度设计的。内容会填满视口的宽度,然后在必要的时候折行。因此,容器的高度由内容天然地决定,而不是容器自己决定。

脱离普通文档流有三种方式:浮动、定位(绝对定位和固定定位)。

BFC

块格式化上下文(Block Formatting Contexts)是 Web 页面可视 CSS 渲染的一部分,是块盒子的布局过程发生的区域。BFC 是网页的一块区域,元素基于此区域布局,BFC 里内容不会跟外部的元素重叠或相互影响。

具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面元素不会在布局上影响到外面元素,并且 BFC 具有普通容器所没有的一些特性。可以把 BFC 理解为一个封闭大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。某些情况下,BFC 中的内容可能还会与别的 BFC 的内容重叠。

BFC 包含创建它的元素内部的所有内容,属于定位方案的普通流。

创建 BFC

  • 根元素(html)
  • 元素 overflow 值不为 visible
  • 元素 float 值不为 none
  • 元素 position 值为 absolute、fixed
  • 元素 contain 值为 layout、content、paint
  • 元素 display 值为 flow-root
  • 元素 display 值为 inline-block
  • 元素 display 值为 flex、 inline-flex 及其直接子元素(弹性元素及其直接子元素)
  • 元素 display 值为 grid、inline-grid 及其直接子元素(网格元素及其直接子元素)
  • 元素 display 值为 table-cell(表格单元格)
  • 元素 display 值为 table-caption(表格标题)
  • 元素 display 值为 table、inline-table、table-row、
    table-row-group、table-header-group、table-footer-group(匿名表格单元格元素)
  • 元素 column-count、column-width 值不为 auto,包括 column-count 值为 1(多列容器)
  • 元素 column-span 值为 all,即使该元素没有包裹在一个多列容器中

使用说明:

使用display: flow-root可以创建无副作用的 BFC。在父级块当中使用display: flow-root可以创建新的 BFC,父级块的所有内容都会参与 BFC。

使用overflow: auto会创建一个包含这个元素的 BFC,通常的做法是设置父级块overflow: auto或者设置其它的非默认的overflow: visible的值。使用 overflow 创建一个新的 BFC,是因为 overflow 属性告诉浏览器你想要怎样处理溢出的内容。当使用这个属性只是为了创建 BFC 的时候,你可能会发现一些不想要的问题,比如滚动条或一些剪切的阴影,需要注意。另外,对于后续的开发,可能不是很清楚当时为什么使用 overflow,所以最好添加一些注释来解释为什么这样做。

也可以使用其他方式,但是有些问题需要注意,比如,使用浮动或display: inline-block方式创建 BFC 的元素宽度会变成 100%,因此需要限制一下元素的宽度,防止因为过宽而换行,导致内容移动到浮动图片的下面。相反,使用display: table-cell方式显示的元素,它的宽度只会刚好容纳其中的内容,因此需要设置一个较大的宽度,强制使其填满剩余空间。

BFC 用途

  • 使用 BFC 浮动定位
  • 使用 BFC 清除浮动
  • 使用 BFC 防止外边距折叠
  • 使用 BFC 防止浮动容器高度塌陷
  • 使用 BFC 防止媒体对象「文字环绕」

IFC

内联格式化上下文(Inline Formatting Contexts)是一个网页的渲染结果的一部分。其中,各行内框(inline boxes)一个接一个地排列,其排列顺序则是根据书写模式的设置来决定的:水平书写,各个框从左边开始水平地排列;垂直书写,各个框从顶部开始水平地排列。

IFC 布局规则

子元素水平方向横向排列,并且垂直方向起点为元素顶部。

子元素只会计算横向样式空间,垂直方向样式空间不会被计算。

在垂直方向上,子元素会以不同形式来对齐(vertical-align)。

能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的行框(line box)。行框的宽度是由包含块(containing box)和与其中的浮动来决定。

IFC 中的“line box”一般左右边贴紧其包含块,但 float 元素会优先排列。

IFC 中的“line box”高度由 CSS 行高计算规则来确定,同个 IFC 下的多个 line box 高度可能会不同。

当 inline-level boxes 的总宽度少于包含它们的 line box 时,其水平渲染规则由 text-align 属性值来决定。

当一个“inline box”超过父元素的宽度时,它会被分割成多个 boxes,这些 oxes 分布在多个“line box”中。如果子元素未设置强制换行的情况下,“inline box”将不可被分割,将会溢出父元素。

框会从包含块的顶部开始,一个接一个地水平摆放。

摆放这些框时,它们在水平方向的 内外边距+边框 所占用的空间都会被考虑; 在垂直方向上,这些框可能会以不同形式来对齐: 水平的 margin、padding、border 有效,垂直无效。不能指定宽高。

行框的宽度是 由包含块和存在的浮动来决定; 行框的高度 由行高来决定。

创建 IFC

块级元素中仅包含内联级别元素。形成条件非常简单,需要注意的是当 IFC 中有块级元素插入时,会产生两个匿名块将父元素分割开来,产生两个 IFC。

IFC 用途

水平居中:当一个块要在环境中水平居中时,设置其为displau: inline-block则会在外层产生 IFC,通过 text-align 属性则可以使其水平居中。

垂直居中:创建一个 IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align: middle,其他的行内元素则可以在此父元素下垂直居中。


CSS文档流
https://xuekeven.github.io/2021/10/03/CSS文档流/
作者
Keven
发布于
2021年10月3日
更新于
2025年8月2日
许可协议