BFC 及其 应用

235 阅读3分钟

BFC

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

BFC(块级格式上下文)是页面盒模型布局中的一种 CSS 渲染模式。

BFC是一个独立的渲染区域,只有块级元素参与,区域内部的元素和区域外部的元素相互不影响

触发方式

一些常见的触发BFC的方式如下,更多的触发方式可以点击这里进行查看:

  1. body节点 ---- 页面的根节点
  2. 浮动的元素 --- float属性不为none的节点
  3. 绝对定位元素 --- position(absolute、fixed)
  4. overflow 除了 visible 之外
  5. display的值为flex, grid, flow-roottable

约束规则

  • 内部box会在垂直方向,一个接一个地放置

  • 属于同一个BFC的两个相邻Box的margin会发生重叠(塌陷)

  • 计算BFC的高度时,浮动子元素也参与计算

  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然

    --> BFC的区域不会与float的元素区域重叠

  • 每个元素的左外边距与包含块的左边界相接触(从左向右),即使浮动元素也是如此。

    --> 这说明BFC中子元素不会超出他的包含块,如果BFC内部某一个元素设置了float,那么这个元素只能浮动到BFC的边界,设置了定位的元素除外

应用场景

外边距塌陷
<style>
  .container {
    border: 1px solid red;
  }
  .box {
    width: 100px;
    height: 100px;
    background: lightblue;
    margin: 100px;
  }
</style>

<div class="container">
  <div class="box"></div>
  <div class="box"></div>
</div>

ImPHjW.png

两个 div 元素都处于同一个 BFC 容器下 (这里指 body 元素) 所以第一个 div 的下边距和第二个 div 的上边距发生了重叠,所以两个盒子之间距离只有 100px,而不是 200px

<style>
  .container {
    border: 1px solid red;
    display: flow-root;
  }
  p {
    width: 100px;
    height: 100px;
    background: lightblue;
    margin: 100px;
  }
</style>

<body>
  <div class="container">
    <p></p>
  </div>
  <div class="container">
    <p></p>
  </div>
</body>

ImPNtH.png

清除浮动
<div style="border: 1px solid #000;">
    <div style="width: 100px;height: 100px;background: #eee;float: left;"></div>
</div>

此时可以发现最外层的那个div是没有高度的,因为内部的div向左浮动了

ImPXcT.png

在之前我们清除浮动的常见做法是在浮动元素的后边多添加一个div,并设置clear:both, 或者一些别的清除浮动的方式

<div style="border: 1px solid #000;">
  <div style="width: 100px;height: 100px;background: #eee;float: left;"></div>
  <div style="clear: both;"></div>
</div>

拥有BFC后,只需要为父元素开启BFC,因为BFC的区域不会与float的元素区域重叠,所以就自动清除了浮动

<div style="border: 1px solid #000;display:flow-root">
  <div style="width: 100px;height: 100px;background: #eee;float: left;"></div>
</div>

ImPcwE.png

防止元素间的重叠覆盖
<!-- 默认情况下,浮动元素会覆盖标注流中除了文本元素之外的元素 -->
<div style="height: 100px;width: 100px;float: left;background: lightblue"></div>
<div style="width: 200px; height: 200px;background: #eee">test content</div>

ImL5CH.png

如果想避免元素被覆盖,可以开启第二个元素的 BFC 特性 -> (BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然)

<div style="height: 100px;width: 100px;float: left;background: lightblue"></div>
<div style="width: 200px; height: 200px;background: #eee;display: flow-root;">test content</div>

ImLbCy.png

display: flow-root

设置了布局方式为flow-root的元素会生成一个块级元素盒子,这个盒子将创建一个新的块级格式化上下文,并定义为格式化根的位置

可见这个属性是CSS中专门可以用来开启BFC的布局,而且不会产生任何的副作用

开启BFC有多种方案

  • overflow:hidden/auto等虽可以清除浮动,但又产生了布局在盒子外部的内容无法显示、无故增加滚动条等多余限制
  • float为left或right能解决margin合并,但又产生了新的浮动;
  • position为fixd或absolute则使元素脱离文档流;
  • display:table相关表格布局在去除margin合并的同时又给布局带来诸多限制,不如普通的display:block灵活;
  • flex弹性布局和grid网格布局又使其子元素严格遵循其特有布局规则……

而使用display:flow-root就不用有这么多的考,因为它在为元素开启BFC的时候,完全不会产生任何的副作用