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

格式化上下文

  • 块格式化上下文 BFC
  • 内联格式化上下文 IFC
  • 灵活(flex)格式化上下文 FFC

块格式化上下文 BFC

BFC布局原则[2]

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

文档最外层元素(<html>元素)使用块布局规则

新的BFC的行为与最外层的文档非常相似,它 在主布局中创造了一个小布局

下列方式会创建 块格式化上下文

创建BFC

  • 根元素(<html>)
  • 浮动元素(元素的 float 不是 none
  • 绝对定位元素(元素的 positionabsolutefixed
  • 行内块元素(元素的 displayinline-block
  • 表格单元格(元素的 displaytable-cell,HTML表格单元格默认为该值)
  • 表格标题(元素的 displaytable-caption,HTML表格标题默认为该值)
  • 匿名表格单元格元素(元素的 displaytabletable-rowtable-row-grouptable-header-grouptable-footer-group(分别是HTML table、row、tbody、thead、tfoot 的默认属性)或 inline-table
  • overflow 计算值(Computed)不为 visible 的块元素
  • display 值为 flow-rootflow-root list-item的元素
  • contain 值为 layoutcontent 或 paint 的元素
  • 弹性元素(displayflexinline-flex 元素的直接子元素)(flex-items)
  • 网格元素(displaygridinline-grid 元素的直接子元素)
  • 多列容器(元素的 column-countcolumn-width (en-US) 不为 auto,包括 column-count1
  • column-spanall 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更Chrome bug)。

块格式化上下文包含创建它的元素内部的所有内容

BFC与浮动

块格式化上下文对浮动定位(参见 float)与清除浮动(参见 clear)都很重要。

浮动定位和清除浮动时只会应用于 同一个BFC内 的元素

浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。

外边距折叠(Margin collapsing)也只会发生在属于同一BFC的块级元素之间。

范例1:让父元素包含子浮动元素,清除内部浮动。(防止子元素设置浮动后,父元素高度塌陷collapse)

让浮动内容和周围的内容等高 (mozilla.org)

BFC作用之清除内部浮动.png

解决浮动脱离文档流的情况给浮动的父元素容器添加属性overflow:auto或者display:flow-root

overflow: auto

创建一个会包含这个浮动的 BFC,通常的做法是设置父元素 overflow: auto 或者设置其他的非默认的 overflow: visible 的值。

副作用: 可能会发现一些不想要的问题,比如滚动条或者一些剪切的阴影

display: flow-root

在父级块中使用 display: flow-root 可以创建新的 BFC。是一种显示创建方法,无副作用。

实际上是在创建一个行为类似于根元素 (浏览器中的<html>元素) 的东西。

或许可以说display: flow-root就是为了创建新的BFC而存在的?

使用display: flow-root ,该容器内的所有内容都参与该容器的块格式上下文,并且浮动不会从元素底部弹出。

flow-root 关键字的意义是,创建的内容本质上类似于一个新的根元素(如 ``所做),并确定这个新的上下文如何创建及其流布局如何实现。

范例2:防止元素被浮动元素覆盖

Exclude external floats

BFC作用之元素覆盖问题.png

设置容器A的属性为display: flow-root或者overflow:hidden等方法,使当前与浮动元素重叠的容器A分离

适用场景: 自适应两(三)栏布局(避免多列布局由于宽度计算四舍五入而自动换行)

范例3:防止外边距重叠(collapse)

块格式化上下文 - margin_collapsing - code sample (mozit.cloud)

  • 解决方法:给任意一个子元素的外侧包裹一个块级元素,并为这个块级元素设置overflow:hidden
  • 注意:应该避免这样添加margin,尽量在同一个方向给元素添加,例如:都添加顶部margin

总结

BFC的两个功能:

  • 父元素包裹住子元素
  • 兄弟元素之间划清界限

行内格式化上下文 IFC

当块容器盒(block container box)不包括任何块级盒(block-level boxes)时,就会创建一个行内格式化上下文(IFC)。

段落创建了一个内联格式上下文,其中在文本中使用诸如 <strong>/<a>/<span>元素等内容

核心概念

行内格式化上下文是一个网页的渲染结果的一部分。其中,各行内框(inline boxes)根据书写模式(writing-mode)顺序排列

  • 对于水平书写模式,各个框从左边开始水平地排列
  • 对于垂直书写模式,各个框从顶部开始水平地排列

行框与行内框:

行框的大小将足以包含该行中所有的行内框(inline boxes)。一个段落实际上是一系列行框的集合,这些行框在块的方向上排列。

如果一个行内框要换行, margins, borders, 以及 padding 的设定均不会在断裂处生效。

在块的方向上对齐

行内框(Inline boxes)可使用vertical-align属性,以不同的方式在块的方向上进行对齐

(与书写方向垂直)

取值:top/bottom/middle/baseline

在行内方向上对齐

text-align 可用于将各行内框(inline boxes)在行框(line box)内对齐。

start/end/left/right/center

浮动造成的效果

如果同一个块格式化上下文中存在一个 float,则这个浮动元素将导致包裹了文本的各行框变短。

1
2
3
4
<div class="box">
<div class="float">I am a floated box!</div>
<p>I am content inside the container.</p>
</div>


  1. 格式化上下文 | 前端知识手册 (gitbooks.io) ↩︎

  2. BFC(边距重叠解决方案) - 掘金 (juejin.cn) ↩︎