【Css】BFC(Block Formatting Context)是块级格式化上下文

111 阅读5分钟

BFC是什么

BFC,全称Block Formatting Context(块级格式化上下文),是CSS布局中的一个重要概念。它是一个独立的渲染区域,只有Block-level box(块级盒子)参与,规定了内部的Block-level Box如何布局,并且与这个区域外部的布局互不干扰。以下是关于BFC的详细解释:

BFC的定义

  • 独立渲染区域:BFC是一个完全独立的布局空间,其中的元素布局不会影响到外部的布局。
  • 块级盒子:只有块级盒子(如div、p等)会参与BFC的布局,而行内盒子(如span、a等)则不会。
  • 渲染规则:BFC内部拥有一套自己的渲染规则,决定了其子元素如何定位,以及与其他元素的相互关系和作用。

BFC的特性

  1. 内部元素不会影响到外部:BFC内部的元素布局变化,不会影响到外部的布局。
  2. 外边距合并的阻止:在BFC中,两个相邻的块级盒子的垂直外边距会发生合并,但在BFC内部,这种合并可以被阻止。
  3. 浮动元素的隔离:BFC可以隔离浮动元素,即BFC内部的浮动元素不会影响到外部的布局,同时BFC也不会被外部的浮动元素所覆盖。
  4. 计算高度时包含浮动元素:在计算BFC的高度时,会考虑到内部的浮动元素的高度。

BFC的触发条件

BFC的触发条件主要有以下几种:

  • 根元素(<html>)默认就是一个BFC。
  • 浮动元素(元素的float属性值不为none)。
  • 绝对定位元素(元素的position属性值为absolutefixed)。
  • 元素的display属性值为inline-blocktable-celltable-captionflexinline-flexgridinline-grid之一。
  • 元素的overflow属性值不为visible(即hiddenautoscroll)。

BFC的应用场景

BFC在CSS布局中有着广泛的应用,主要用于解决以下布局问题:

高度塌陷:当子元素浮动时,父元素可能会出现高度塌陷的问题。通过触发父元素的BFC,可以解决这个问题。

<style> 
  .wrap{
    overflow: hidden;
  }
  p{
    background-color: pink;
    width: 200px;
    line-height: 200px;
    text-align: center;
    margin: 100px;
  }
</style>  
<body>  
  <p>内容1</p>  
  <div class="wrap">
  <p>内容2</p>  
</div>
</body>  

由显示以下的结果可知,我们设置了每个p之间的边距为100px,两个相加应该为200px,当时实际出来的效果两个p之间的间距只有100px。

8d238cfb3767eb39f7d8c9b25b531e7.png

问题: 外边距合并:在垂直方向上,相邻的块级元素的外边距可能会发生合并。通过触发BFC,可以阻止这种合并。 解决方法:可以在p的外面包裹一个容器,并且触发这个容器生成一个BFC,那么两个p就不属于一个BFC,则不会出现margin重叠

<style>  
  p{
    background-color: pink;
    width: 200px;
    line-height: 200px;
    text-align: center;
    margin: 100px;
  }
</style>  
<body>  
    <p>内容1</p>  
    <p>内容2</p>  
</body>
19c9e0671f5477d581510f38ed59ef0.png

浮动元素的覆盖问题:通过触发BFC,可以使BFC内部的浮动元素不会覆盖到BFC外部的元素。

<style>  
 .par{
  border: 5px solid pink;
  width: 300px;
 }
 .child{
  border: 5px solid skyblue;
  width: 100px;
  height: 100px;
  float: left;
 }
</style>  
<body>  
    <div class="par">
      <div class="child"></div>
      <div class="child"></div>
    </div>

由以下显示的结果可知,在BFC计算高度的时候,浮动元素也会参与,所以我们可以触发.par元素生成BFC,则内部浮动元素计算高度的时候也会计算

95fb49aa6d995d9dc9c960c0ccd4376.png

解决方法:在bar添加属性overflow。.par 的 overflow: hidden; 属性确保了它成为一个 BFC,从而解决了高度塌陷的问题,并允许它的边框正确地包围浮动的子元素。

这里的par为300px,而child为100px,overflow: hidden的意思为内容会被修剪,并且超出部分不可见。也就是除了包含在par里面的子元素高度为100px之外剩下的200px都会被修剪掉。如果外面这个时候设置的子元素宽度超出par的宽度,那么可视页面中的盒子的宽度最多为300px。

.par{
  border: 5px solid pink;
  width: 300px;
  overflow: hidden;
 }

双栏或三栏自适应布局:在某些情况下,可以使用BFC来实现双栏或三栏的自适应布局。

<style>  
body{
  width: 300px;
  position: relative;
}
.aside{
  width: 100px;
  height: 150px;
  float: left;
  background-color: pink;
}
.main{
  height: 200px;
  width: 200px;
  background-color: skyblue;
}
</style>  
<body>  
    <div class="aside"></div>
    <div class="main"></div>
</body>  
07670dcc17939bea5e0775e4cb5ea84.png 由以下结果可知,每个元素的左边距与包含块的左边界相接触 浮动是会脱离常规文档流(normal flow)的约束,并在一定程度上表现得像是“独立开来”的一块内容 。main属于文档内的元素和aside属于文档之外的元素。所以有两种解决方法

方法一:将main变成和aside一样为浮动元素,属于文档流之外的东西

body{
  width: 300px;
  position: relative;
}
.aside{
  width: 100px;
  height: 150px;
  float: left;
  background-color: pink;
}
.main{
  height: 200px;
  float: left; /*float: left;*/
  width: 200px;
  background-color: skyblue;
}

方法二:撤销aside的浮动元素

body{
  width: 300px;
  position: relative;
}
.aside{
  width: 100px;
  height: 150px;
  /* float: left; */
  background-color: pink;
}
.main{
  height: 200px;
  width: 200px;
  background-color: skyblue;
}