浅谈BFC

一、什么是BFC

BFC: 块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,
是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域
引用MDN

二、BFC生成条件

  • 根元素()

  • 浮动元素(元素的 float 不是 none)

  • 绝对定位元素(元素的 position 为 absolute 或 fixed)

  • overflow 值不为 visible 的块元素

  • display 值为 flow-root 的元素

  • 弹性元素(display为 flex 或 inline-flex元素的直接子元素)

  • 行内块元素(元素的 display 为 inline-block)

  • 表格单元格(元素的 display为 table-cell,HTML表格单元格默认为该值)

  • 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)

  • 匿名表格单元格元素(元素的 display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table)

  • contain 值为 layout、content或 paint 的元素

  • 网格元素(display为 grid 或 inline-grid 元素的直接子元素)

  • 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1)

  • column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。
    引用MDN

三、BFC特性

  • 内部盒子在垂直方向上 一个接一个排练
  • 内部盒子在垂直方向上会出现上下margin重叠,间距以较大为准
  • BFC区域不会与float浮动元素重叠
  • 计算BFC区域高度时,浮动元素也参与计算
  • BFC是页面上一个独立的容器,容器里面的元素不会影响外面的元素,反之也如此

注意
父子元素margin重叠问题,可以通过给父元素设置overflow:hidden,使其形成一个BFC区域即可解决

3.1 内部盒子在垂直方向上会出现上下margin重叠,间距以较大为准
  <head>
     <style type="text/css">
         .container {
             width: 100px;
             height: 100px;
             background-color: red;
             overflow: hidden;
         }
         .box1 {
             width: 30px;
             height: 30px;
             margin-bottom: 10px;
             background-color: green;
         }
         .box2 {
             width: 30px;
             height: 30px;
             margin-top: 20px;
             background-color: orange;
         }
     </style>

  </head>
  <body>
     <div class="container">
         <div class="box1"></div>
         <div class="box2"></div>
     </div>
  </body>

如图
在这里插入图片描述

以上示例给container盒子设置overflow:hidden形成BFC,内部的两个盒子就会出现上下margin重叠现象,
两个盒子的间距取margin较大值

3.1.1 假如不给container盒子设置overflow:hidden会怎样呢?

box1和box2还是会出现上下margin重叠现象,因为整个根元素就是一个BFC区域

3.1.2 如何让两个盒子的margin都生效?

若要两个盒子的margin都生效则需要让两个盒子在不同的BFC里,即需要给box1或box2再嵌套一层并设置overflow:hidden,形成一个新的BFC。
直接给box1或box2设置overflow:hidden则不会生效,因为只有BFC容器里面的元素才不会影响外面的元素,而像box1和box2兄弟元素是属于外层container的子元素,还是会相互影响的

解决方法:对box1再嵌套一层

  .wrapper {
      overflow: hidden;
  }

  <div class="container">
      <div class="wrapper">
          <div class="box1"></div>
      </div>
      <div class="box2"></div>
  </div>

如图
在这里插入图片描述

3.2 BFC区域不会与float浮动元素区域重叠
3.2.1 默认情况下

标准流中的元素会与float浮动元素重叠,即每个元素的左边都会与包含该盒子的父元素左边对齐
如:box1盒子为浮动元素,box2为标准流中元素,它们都与container盒子左边对齐。
但虽然浮动元素与后续的块级元素重叠了,但块级元素中的文本、块级元素内的行内元素、块级元素内的行内块元素都不会被遮挡,从而形成我们常见的如:字围现象

  <head>
      <style type="text/css">
          .container {
              width: 100px;
              height: 100px;
              background-color: red;
          }
          .box1 {
              width: 40px;
              height: 40px;
              background-color: green;
              opacity: 0.5;
              float: left;
          }
          .box2 {
              width: 80px;
              height: 80px;
              background-color: orange;
          }
      </style>
  </head>
  <body>
  <div class="container">
      <div class="box1">123</div>
      <div class="box2">456</div>
  </div>
  </body>

如图
在这里插入图片描述

3.2.2 BFC区域不会与float浮动元素区域重叠

为box2盒子添加属性overflow: hidden 让其形成BFC区域,其他不变

  .box2 {
      width: 40px; //修改宽度为40px
      height: 40px; //修改高度为40px
      background-color: orange;
      overflow: hidden; //新增加的属性
  }

如图
在这里插入图片描述

3.2.3 此时如果给box2盒子再多设置一个属性margin-left: 10px会怎样呢?
  .box2 {
     width: 40px;
     height: 40px;
     background-color: orange;
     overflow: hidden;
     margin-left: 10px; //新增加的
  }

如图:不会变
在这里插入图片描述

是不是很疑惑,既然BFC区域不会与float浮动元素区域重叠,那么给box2盒子设置的左边距应该是以box1盒子为参照物啊,为什么左边距没有出现?
我的理解是,虽然BFC区域特性是不会与float元素区域重叠,但BFC区域内的 块级元素 的参照物还是以标准流中的元素为准,所以此时box2盒子是以container盒子为参照物

3.2.4 如果给box2盒子设置margin-left: 50px;则会看到box2盒子和box1盒子有10px的距离

如图
在这里插入图片描述

3.2.5 此时如果为box2盒子添加属性display: inline-block 同样让其形成BFC区域,再为其添加margin-left: 10px属性,那会不会和上面一样,也不出现左边距呢?
  .box2 {
     width: 40px;
     height: 40px;
     background-color: orange;
     display: inline-block; //新增加的
     margin-left: 10px; //新增加的
  }

如图:
在这里插入图片描述

是不是又疑惑了?为什么这次又出现了左边距呢?这都什么情况
我的理解是:浮动流对后续标准流中的行内块元素或行内元素都会视为文本,而浮动流不会遮挡文本,所以它们会沿着浮动流的同一行继续外后排
也就是说浮动元素的脱标有字围现象,而它的字围现象不仅仅只针对文字,这种现象也会把行内和行内块元素也当作文字,所以我们不能直接无视浮动元素的存在

3.2.6 自适应两栏布局

根据BFC区域不会与float浮动元素区域重叠的特性,可以制作出自适应两栏布局

  <head>
      <style type="text/css">
          .container {
              width: 100px;
              height: 100px;
              background-color: red;
          }
          .box1 {
              width: 40px;
              height: 40px;
              background-color: green;
              float: left;
          }
          .box2 {
              height: 40px;
              background-color: orange;
              overflow: hidden;
          }
      </style>
  </head>
  <body>
  <div class="container">
      <div class="box1">123</div>
      <div class="box2">456</div>
  </div>
  </body>

如图
在这里插入图片描述

3.3 计算BFC区域的高度时,浮动元素也参与计算
3.3.1 默认情况下

标准流元素是无法包裹住浮动元素的,这也就导致浮动元素无法参与父元素高度的计算,也就出现了我们常说的 高度塌陷问题

  <head>
      <style type="text/css">
          .container {
              width: 100px;
              border: 1px solid red;
          }
          .box1 {
              width: 40px;
              height: 40px;
              background-color: green;
              opacity: 0.5;
              float: left;
          }
      </style>
  </head>
  <body>
  <div class="container">
      <div class="box1">123</div>
  </div>
  </body>

如图
在这里插入图片描述

3.3.2 BFC区域能够包裹住浮动的子元素,因此浮动元素也参与BFC区域下高度的计算,从而也解决了高度塌陷问题

为container盒子添加属性overflow: hidden 让其形成BFC区域,其他不变

  .container {
      width: 100px;
      overflow: hidden;
      border: 1px solid red;
  }

如图
在这里插入图片描述

BFC中浮动流和定位流区别

  • 1: 浮动流脱标有字围现象,不仅针对块级元素的文本,对后续标准流中的行内块元素、行内元素也都会视为文本,并不会遮挡它们,会让它们沿着浮动元素同一行往后排
  • 2: 定位流脱标会直接遮挡标准流,无论是块级元素还是行内元素
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值