3W=>BFC

124 阅读3分钟

什么是BFC

BFC,全称为「Block Formatting Context」,即块级格式化上下文。它是 CSS 中的一个概念,用于描述在文档中创建的一种独立的块级容器,这个容器内部的元素按照一定的规则进行布局和渲染。

BFC 的主要作用是控制元素的布局和定位,以确保页面的呈现在各种情况下都能够按照预期进行。

以下是 BFC 的一些特性和作用:

  1. 内部元素不会溢出: BFC 内部的元素不会溢出到外部的容器中,从而避免一些布局问题。(老生常谈,顾名思义,这都不知道 回炉重造)
  2. 解决浮动元素高度塌陷: 当一个元素的 overflow 属性设置为 hiddenautoscroll 时,它会创建一个 BFC,并且可以用来清除浮动元素带来的高度塌陷问题。
  3. 垂直边距折叠: 相邻两个 BFC 的相块级元素的垂直外边距不会折叠。
  4. 定位控制: BFC 可以影响元素的定位,使得浮动元素也能参与定位计算。
  5. 自包含: BFC 是一个独立的上下文,不受外部影响,其内部的元素布局互相不影响,从而避免一些样式冲突。

清除浮动

当你做一个headder的时候 我需要logo保持在左边,User头像保持在右边(当然space-between可以,但我们讨论一下float的实现)

当你开开心心吃着火锅唱着歌 写下了如下的代码时

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .outer {
      width: 100vw;
      border: 2px solid greenyellow;
    }
    .logo {
      background: rgba(144, 144, 253, 0.507);
      width: 30px;
      height: 10px;
      float: left;
    }
    .user {
      background: rgba(76, 253, 230, 0.507);
      width: 30px;
      height: 10px;
      float: right;
    }
    html,
    body {
      margin: 0;
      padding: 0;
    }
  </style>
</head>
<body>
  <div class="outer">
    <div class="logo"></div>
    <div class="user"></div>
  </div>
</body>
</html>

点击GoLive!

图片.png

哈哈 父元素塌陷啦!

但是你只要稍加修改

>>>    
    .outer {
      width: 100vw;
      border: 2px solid greenyellow;
|     overflow: hidden;
    }
>>>

就会得到

图片.png

成功啦!

总结:BFC 使得让浮动内容和周围的内容等高,使得浮动元素也能参与定位计算。

垂直外边距折叠问题

相邻两个 BFC 的相块级元素的子元素的垂直外边距不会折叠。

在BFC下相邻两个元素会像预期那样 折叠外边距

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .outer {
      overflow: hidden;
    }
    .inner1 {
      width: 100px;
      height: 300px;
      background: rgba(144, 144, 253, 0.507);
      margin: 100px;
    }
    .inner2 {
      width: 100px;
      height: 300px;
      background: rgba(76, 253, 230, 0.507);
      margin: 100px;
    }
  </style>
</head>
<body>
  <div class="outer">
    <div class="inner1"></div>
    <div class="inner2"></div>
  </div>
</body>

  


</html>

这时你拥有了两个上下排列的盒子了。

BFC上下盒子.png

这时候上下两个盒子的间距会是预想的200px吗?

图片.png

显然不会!因为这是一个BFC下的两个相邻元素 和普通文档流下的两个元素几乎一样(当前工况下) Nothing New.

但是只要稍加修改

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .outer {
      overflow: hidden;
    }
    .inner1 {
      width: 100px;
      height: 300px;
      background: rgba(144, 144, 253, 0.507);
      margin: 100px;
    }
    .inner2 {
      width: 100px;
      height: 300px;
      background: rgba(76, 253, 230, 0.507);
      margin: 100px;
    }
  </style>
</head>
<body>
  <div class="outer">
    <div class="inner1"></div></div><div class="outer">
|    <div class="inner2"></div>
  </div>
</body>
</html>

就会得到

图片.png

WOW!外边距不塌缩了!

总结:不同BFC下的子元素不会有垂直边距塌缩问题。

定位控制

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .outer {
      width: 15vw;
      border: 2px solid greenyellow;
      overflow: hidden;
    }
    .logo {
      background: rgba(144, 144, 253, 0.507);
      width: 30px;
      height: 10px;
      float: left;
    }
    .user {
      background: rgba(76, 253, 230, 0.507);
      width: 30px;
      height: 10px;
      float: right;
    }
    html,
    body {
      margin: 0;
      padding: 0;
    }
  </style>
</head>
<body>
  <div class="outer">
    <div class="logo"></div>
    <div class="user"></div>
  </div>
</body>
</html>

图片.png

As you can see, 外层盒子只有15%的视窗宽度 内部logo和user分别赋予 左右浮动。然而,浮动了 但没完全浮动,这也就是上文所说的BFC会对子元素进行定位控制也就是说 子元素只有在BFC盒子内部有限地浮动

总结

BFC就是一个独立于传统文档流的区块格式化上下文。文档流上类似于ifram,但是对于它内部的元素又不太一样,他会尊重浮动元素对自己的影响,自己的高度也会随内部浮动元素的变化;但是他也会管好自己的子浮动元素,不会超出自己的管辖范围,这种家长特性感ha?