BFC等Formatting Contexts浅析

盒模型

CSS 盒模型描述了通过 文档树中的元素 以及相应的 视觉格式化模型(visual formatting model) 所生成的矩形盒子。

什么是 BFC

BFC(Block formatting context) 直译为”块级格式化上下文”。它是一个独立的渲染区域,只有 Block-level box 参与,它规定了内部的 Block-level Box 如何布局,并且与这个区域外部毫不相干。同理,还有 inline-level box,run-in box

BFC 布局规则

  • 内部的 Box 会在垂直方向,一个接一个地放置。
  • Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Boxmargin 会发生重叠。
  • 每个元素的 margin box 的左边, 与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  • BFC 的区域不会与 float box 重叠。
  • BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  • 计算 BFC 的高度时,浮动元素也参与计算。

哪些元素是 BFC

  • 根元素,即 HTML 元素
  • float 属性不为 none
  • positionabsolutefixed
  • displayinline-block, table-cell, table-caption, flex, inline-flex
  • overflow 不为 visible

BFC 有什么用

  • 自适应两栏布局
  • 清除内部浮动(如给父元素加 overflow:hidden
  • 分属于不同的 BFC 时可以阻止 margin 重叠

什么是 FC

FC 的全称是:Formatting Contexts,是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。

FC 一共包含 BFC、IFC、GFC、FFC 四种类型。CSS2.1 规范中只有 BFC、IFC。CSS3 推出 GFC、FFC 两种新类型。

IFC

IFC(Inline Formatting Contexts) 直译为”内联格式化上下文”,IFCline box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的 padding/margin 影响)。

IFC 特性

  • IFC 中的 line box 一般左右都贴紧整个 IFC,但是会因为 float 元素而扰乱。float 元素会位于 IFC 与与 line box 之间,使得 line box 宽度缩短。
  • IFC 中时不可能有块级元素的,当插入块级元素时(如 p 中插入 div)会产生两个匿名块与 div 分隔开,即产生两个 IFC,每个 IFC 对外表现为块级元素,与 div 垂直排列。

IFC 作用

  • 水平居中:当一个块要在环境中水平居中时,设置其为 inline-block 则会在外层产生 IFC,通过 text-align 则可以使其水平居中。
  • 垂直居中:创建一个 IFC,用其中一个元素撑开父元素的高度,然后设置其 vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。

GFC

GFC(GridLayout Formatting Contexts) 直译为”网格布局格式化上下文”,当为一个元素设置 display 值为 grid 的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器(grid container)上定义网格定义行(grid definition rows)和网格定义列(grid definition columns)属性各在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)为每一个网格项目(grid item)定义位置和空间。

GFC 将改变传统的布局模式,他将让布局从一维布局变成了二维布局。简单的说,有了 GFC 之后,布局不再局限于单个维度了。这个时候你要实现类似九宫格,拼图之类的布局效果显得格外的容易。

FFC

FFC(Flex Formatting Contexts) 直译为”自适应格式化上下文”,display 值为 flex 或者 inline-flex 的元素将会生成自适应容器(flex container)

Flex Box 由伸缩容器和伸缩项目组成。通过设置元素的 display 属性为 flexinline-flex 可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素,而设置为 inline-flex 的容器则渲染为一个行内元素。

伸缩容器中的每一个子元素都是一个伸缩项目。伸缩项目可以是任意数量的。伸缩容器外和伸缩项目内的一切元素都不受影响。简单地说,Flexbox 定义了伸缩容器内伸缩项目该如何布局。

整体来说,FFCBFC 有点儿类似,但仍有以下几点区别:

  • Flexbox 不支持 ::first-line::first-letter 这两种伪元素
  • vertical-alignFlexbox 中的子元素是没有效果的
  • floatclear 属性对 Flexbox 中的子元素是没有效果的,也不会使子元素脱离文档流(但是对 Flexbox 是有效果的!)
  • 多栏布局(column-*) 在 Flexbox 中也是失效的,就是说我们不能使用多栏布局在 Flexbox 排列其下的子元素
  • Flexbox 下的子元素不会继承父级容器的宽
---- 本文结束,感谢您的阅读 ----