格式化上下文

formatting context.

在 CSS 中, 元素所处的环境有两种:

  • 块格式化上下文( Block formatting context )
  • 行内格式化上下文( Inline formatting context )

格式化的意思是, 在这个环境中元素应当被初始化, 初始化的过程就是元素在此环境中的布局过程.

块级格式化上下文

Block formatting context 简称 BFC. 块格式化上下文是一个比较抽象的概念. 可以把它想象成一个大箱子, 很多元素装在里面, 箱子把它们和外面的元素隔开.

w3c文档中是这样定义BFC的:

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.

# BFC中, 框是如何被布局的?

在BGC中, 框会从包含块的顶部开始, 一个接一个地被垂直放置.

两个相邻的块级框之间的垂直距离取决于它们的 'margin' 属性. 两者的垂直外边距( top , bottom )会叠加( collapse ).

每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反). 即使存在浮动也是如此, 除非这个元素也创建了一个新的BFC, 但元素的内容区域会由于浮动而压缩.

计算BFC高度是包含其浮动子元素的.

# BFC的作用

它与普通的块框类似,不同之处在于:

  • 清除内部浮动, 防止容器高度塌陷

毕竟计算BFC高度是包含其浮动子元素的.

详见下一节[浮动]

  • 阻止外边距折叠

css中定义了外边距折叠的规则: 仅当两个块级元素相邻并且在同一个块级格式化上下文时, 它们垂直方向之间的外边距才会叠加.

因此, 阻止外边距折叠只需产生新的 BFC .

  • 防止元素被浮动元素覆盖

# 如何触发BFC?

  • 浮动元素 , float除了none以外的值
  • 绝对定位元素, position: absolute | fixed
  • 非块级盒子的块级容器, display: inline-block | table-cell | table-caption
  • overflow: hidden | auto | scroll 除了visible 以外的值
  • fieldset元素 不过还没有规范化

其中display:table本身不会创建BFC, 但是它产生匿名框(anonymous boxes), 匿名框中的display:table-cell可以创建新的BFC. 所以display:table可以间接地触发BFC.

# CSS3 flow root

在 CSS3 中, 对块格式化上下文这个概念做了改动, 改名为flow root

对于触发方式也做了修改, 更加准确: The value of 'position' is neither "static" nor "relative".

# IE Hack -- hasLayout

现代浏览器是有BFC的, IE8+以后的BFC与标准相似, 但IE6-7的显示引擎使用的是一个称为布局(layout)的内部概念, 由于这个显示引擎自身存在很多的缺陷, 直接导致了IE6-7的很多显示bug.

当我们说一个元素"得到layout", 或者说一个元素"拥有layout"的时候, 我们的意思是指它的微软专有属性hasLayout为此被设为了 true. 我们可以将这种机制等同于BFC.

IE6-7使用布局的概念来控制元素的尺寸和定位, 那些拥有布局(has layout)的元素负责本身及其子元素的尺寸设置和定位. 如果一个元素的 hasLayout 为false, 那么它的尺寸和位置由最近拥有布局的祖先元素控制.

有些html元素本身就有layout属性, hasLayout为true时, 就说这个元素有布局.

以下是可以触发hasLayout的css属性, 仅限IE6-7:

  • display: inline-block
  • height: (除 auto 外任何值)
  • width: (除 auto 外任何值)
  • float: (left 或 right)
  • position: absolute;
  • writing-mode: tb-rl;
  • zoom: (除 normal 外任意值)

在 IE7 中, overflow 也变成了一个 layout 触发器:

  • overflow: hidden|scroll|auto
  • overflow-x|-y: hidden|scroll|auto

行内格式化上下文

Inline formatting context

References