【CSS】BFC

202 阅读3分钟

简介

BFC(Block Formatting Context)即块级格式化上下文,它既不是一个CSS属性,也不是一段代码,而是CSS2.1规范中的一个概念,决定元素的内容如何渲染以及与其它元素的关系的交互。

可以将BFC想象成一个箱子,BFC的内容就相当于箱子中的物品,将物品摆在箱子里,能避免与其他箱子中的物品混淆,还能保护它们不被破坏。

BFC的5条规则

  • BFC有隔离作用,内部元素不会受外部元素的影响(反之亦然)
  • 一个元素只能存在于一个BFC中,如果能同时存在于两个BFC中,就违反了BFC的隔离规则
  • BFC内的元素按正常流排列,元素之间的间隙由元素的外边距(margin)控制
  • BFC中的内容不会与外面的浮动元素重叠
  • 计算BFC的高度,需要包括BFC内的浮动子元素的高度

创建BFC需满足的条件

  • 根元素,也就是html元素
  • float属性不为none的浮动元素
  • position属性是absolute或fixed的定位元素
  • display属性为inline-block、table-cell(相当于td或th元素)、table-caption(相当于caption元素)或伸缩盒(flex和inline-flex)的元素
  • overflow属性不为visible的块级元素

如果要创建BFC,必须满足以上条件中的一个

BFC的用途

BFC的常规用途有三个:清除浮动、解决外边距塌陷和宽度自适应的两栏布局

清除浮动

例1: 当一个元素被定义为浮动之后,附近的文件,即使不是相邻的关系,也会环绕着它。

<style type="text/css">
    ul {
        overflow: hidden; /**创建BFC**/
    }
</style>
<ul>
    <li style="float: left;background-color: aliceblue;">第一个元素</li>
</ul>
<span>外部文字</span>

让li的父级元素ul创建BFC后(例如给ul的css属性overflow定义为hidden),由于BFC有隔离作用,就能防止外部的文字环绕。

例2: 浮动的元素会脱离正常的文档流,如果附近有其他元素,并且这个元素在正常流中,将会与其重叠。

<style type="text/css">
    span {
      float: left;
      background-color: aliceblue;
    }
    div {
      width: 150px;
      height: 60px;
      background-color: antiquewhite;
      overflow: hidden; /**创建BFC**/
    }
  </style>

例3: 如果一个元素未定义高度,并且有浮动的子元素,那么将会引起元素的高度的塌陷(height collapsing)

<style type="text/css">
    ul {
      background-color: aliceblue;
      overflow: hidden; /**创建BFC**/
    }
    ul li {
      width: 100px;
      height: 20px;
      background-color: antiquewhite;
    }
</style>
<ul>
    <li style="float: left;">第一个元素</li>
</ul>

解决外边距塌陷

关于外边距塌陷的几种情况可参考这篇

以父元素和子元素之间的塌陷为例:

<style type="text/css">
    .wrapper {
      width: 100px;
      height: 100px;
      background-color: aliceblue;
    }
    .inner-wrapper {
      overflow: hidden; /**创建BFC**/
      width: 100px;
      height: 100px;
      background-color: antiquewhite;
    }
    p {
      width:50px;
      background-color: aqua;
    }
</style>
<div class="wrapper"></div>
<div style="margin-top: 10px;" class="inner-wrapper">
    <p style="margin-top: 10px">p元素内容</p>
</div>

宽度自适应两栏布局

要求:左边固定,右边自适应

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>宽度自适应两栏布局</title>
  <style type="text/css">
    *{margin: 0; padding: 0;}
    .left {
      float: left;
      width: 100px;
      height: 100px;
      background-color: aliceblue;
    }
    .right {
      overflow: hidden;
      height: 100px;
      background-color: antiquewhite;
    }
  </style>
</head>
<body>
  <div>
    <div class="left">左边固定</div>
    <div class="right">
      右边自适应
    </div>
  </div>
</body>
</html>