跳到主要内容

格式化上下文

网络热门面试题:什么情况下触发BFC?

网络答案如下:

  • 根元素(html)
  • float属性不为none
  • position为absolute或fixed
  • display为inline-block, table-cell,table-caption, flex, inline-flex
  • overflow不为visible

首先,这个问题本身就是错误的

BFC全称块格式化上下文(Block Formatting Context),前面的动词应该是establish(创建设立),和触发没有关系,触发是trigger,在标准里也没有和bfc连用过

css排版布局主要使用的就是box盒模型和Formatting Context, box本身放在什么位置就需要一个上下文,Formatting有规制整理的意思,需要的上下文就叫Formatting Context。

css标准里面明确讲到Formatting有4种

正常流:

  • block formatting context block container => block-level box
  • inline formatting context line box => inline-level box

弹性布局:

  • flex formatting context flex container => flex item

网格布局:

  • grid formatting context grid container => grid items

CSS2.1给block container中的block container取了一个名字

block container + block-level box => block box => block

BFC是元素创建的,但是它只是给排版用的信息,并不是元素本身,其难点在于和其他特性的互动,比如margin,一个容器是否包含内部元素的margin等

float浮动到父元素的左边或右边是不管父容器是否创建了BFC

position定位的起点依赖containing block,和BFC没有任何关系只和position的属性有关

image-20220813180030951

block在overflow为visible的时候是不产生BFC的,这是唯一一个特例,进入MDN查看以上三个示例

通过案例了解格式化上下文

案例资源
src/components/FormattingContext/styles.module.css
#margin {
margin: 20px;
width: 500px;
outline: solid 20px rgba(0, 255, 0, 0.2);
}
#bfc {
width: 500px;
overflow: visible;
outline: solid 20px rgba(0, 0, 255, 0.2);
overflow: hidden;
margin: 20px;
}
#containing-block {
width: 400px;
overflow: visible;
outline: solid 20px rgba(255, 255, 0, 0.2);
margin: 20px;
position: relative;
}
#parent-box {
width: 200px;
outline: solid 1px green;
}
#inner1 {
float: right;
background-color: lightgreen;
width: 50px;
height: 50px;
}
#inner2 {
position: absolute;
right: 0px;
background-color: lightblue;
width: 50px;
height: 50px;
}
#inner3 {
margin: 30px;
background-color: red;
outline: solid 30px rgba(255, 0, 0, 0.2);
width: 50px;
height: 50px;
}

使用基础的盒模型,可以观察到外边距重叠,containing block的marginTop相对与block formatting context

margin:20px;
parent box
containing block
block formatting context/margin:20px

在parent box中添加一个向右浮动的子元素,parent box的overflow默认为visible,浮动脱离了文档流,所以parent box仅包含了内容,不包含浮动。所以在创建包含浮动元素的 BFC 时,通常的做法是设置父元素 overflow: auto 或者其它除默认的 overflow: visible 以外的值

margin:20px;
float: right
parent box
containing block
block formatting context/margin:20px

增加一个position为absolute的元素,父元素parent box未设置position,containing block设置了relative,所以相对其定位

margin:20px;
float: right
position: absolute
parent box
containing block
block formatting context/margin:20px

在增加了一个margin为30px的子元素,marginLeft单独撑开,而marginTop和父元素parent box的marginTop共同作用使parent box下移10px

margin:20px;
float: right
position: absolute
margin: 30px
parent box
containing block
block formatting context/margin:20px

此外,当前文档中的几个案例都有marginTop为20px,和p元素默认的20px重叠,之所以现在有空隙是因为给每个组件包了一个容器设置了样式

#formatting-custom-box{
overflow: hidden;
margin-bottom: 20px;
}