CSS 基础:BFC(块级格式化上下文)

288 阅读4分钟

什么是BFC

BFC(Block Formatting Context),块级格式化上下文:

  • block 块级盒子
  • Formatting Context CSS2.1 规范中的一个概念,指的是页面中的一块渲染区域,并且有一套渲染规则,决定了其子元素将如何定位,以及和其他元素的关系、相互作用

视觉格式化模型(visual formatting model

视觉格式化模型是根据基础盒模型(basic box model)将文档中的元素转换为一个个盒子的实际算法,规定了用户端在媒介中如何处理文档树

盒模型

基础盒模型(basic box model):当浏览器对一个render tree进行渲染时,浏览器的渲染引擎就会根据基础盒模型将所有元素划分为一个个矩形的盒子,这些盒子的外观由样式决定。

每个盒子的布局由以下因素决定:

  • 盒子的尺寸
  • 盒子的类型:行内盒子 (inline)、行内级盒子 (inline-level)、原子行内级盒子 (atomic inline-level)、块级盒子 (block-level)
  • 定位:正常流、浮动、绝对定位
  • 文档树中当前盒子的子元素 或 兄弟元素
  • 视口(viewport) 的尺寸 和位置
  • 盒子内部图片的尺寸
  • 其他某些外部因素

盒子的类型:

  • 块级盒(block box

    • 当元素的displayblock,list-item或 table时,它是块级元素
    • 视觉上呈现为块,竖直排列
    • 块级盒参与块格式化上下文创建
    • 块级盒子用于描述它和父、兄弟元素之间的关系
    • 每个块级元素至少生成一个块级盒,称为主要块级盒(principal block-level box)。一些元素,比如<li>,生成额外的盒来放置项目符号,不过多数元素只生成一个主要块级盒。
  • 行内盒(inline box

    • 当元素的displayinline,inline-block或inline-table时,为行内级元素
    • 视觉上它将内容与其它行内级元素排列为多行;典型的如段落内容,有文本(可以有多种格式譬如着重),或图片,都是行内级元素;
    • 行内级元素生成行内级盒(inline-level boxes),参与行内格式化上下文(inline formatting context)。同时参与生成行内格式化上下文的行内级盒称为行内盒(inline boxes)。所有display:inline的非替换元素生成的盒是行内盒;
    • 不参与生成行内格式化上下文的行内级盒称为原子行内级盒(atomic inline-level boxes)。这些盒由可替换行内元素,或 display 值为 inline-block 或 inline-table 的元素生成,不能拆分成多个盒;
  • 匿名盒(anonymous box) 匿名盒分为匿名块盒与匿名行内盒,因为匿名盒没有名字,不能利用选择器来选择它们,所以它们的所有属性都为inherit或初始默认值;

视觉格式化模型的计算,都取决于一个矩形的边界,这个矩形,被称作是 包含块( containing block ) 。 一般来说,(元素)生成的框会扮演它子孙元素包含块的角色;我们称之为:一个(元素的)框为它的子孙节点建造了包含块。包含块是一个相对的概念。

定位方案:

  • 常规流 Normal flow
    • 常规流中盒一个接一个排列
    • positionstatic relative同时float:none的时候会触发常规流
  • 浮动 float
    • 导致常规流环绕在周围(除非清除浮动)
  • 绝对定位
    • 绝对定位导致盒从常规流中被移除,不影响原来的布局

BFC

块格式上下文是一个独立的渲染区域只有块级盒子参与,规定了内部盒子如何布局,并且和外部毫不相干。

生成条件(满足一条即可):

  • 根元素
  • 浮动(float不为none
  • 绝对定位元素(fixed absolute
  • 行内块元素(inline-block
  • 表格单元格(table-cell
  • 表格标题(table-caption
  • 匿名表格单元格
  • overflow不为visible
  • displayflow-root
  • 弹性元素
  • 网格元素
  • 多列容器

BFC 包含创建上下文元素的所有子元素,但不包括创建了新BFC的子元素内部的元素:

// BFC类代表块格式样式
<div id='div_1' class='BFC'>
    <div id='div_5' class='BFC'>
        <div id='div_6'></div>
        <div id='div_7'></div>
    </div>
</div>

div1 创建了一个块格式上下文包括div5,但是div5又创建了新的BFC所以div6 div7就不属于外层BFC,或者说同一元素只能存在于一个BFC中。

BFC的内部规则:

  • 内部盒会垂直排列
  • 内部的margin会重叠
  • 子元素的margin box的左边会和BFCborder box的左边相接触
  • 内部元素不会影响外面,反之亦然
  • BFC区域不会和浮动重叠
  • 计算BFC高度会包含浮动元素

应用:

  • 阻止margin重叠
  • 可以包含浮动元素,清除内部浮动(清除浮动的原理是两个div都位于同一个 BFC 区域之中)
  • 自适应两栏布局
  • 可以阻止元素被浮动元素覆盖