BFC

827 阅读3分钟

BFC:块级格式化上下文

一个BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。

BFC的最显著的效果就是建立一个隔离的空间,断绝空间内外元素间相互的作用。

触发BFC的条件

  • 根元素或其它包含它的元素
  • 浮动元素 (元素的 float 不是 none)
  • 绝对定位元素 (元素具有 position 为 absolute 或 fixed)
  • 内联块 (元素具有 display: inline-block)
  • 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
  • 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
  • 具有overflow 且值不是 visible 的块元素
  • 弹性盒(flex或inline-flex)
  • display: flow-root
  • column-span: all

BFC的约束规则

  • 内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流)
  • 垂直方向上的距离由margin决定。(完整的说法是:属于同一个BFC的两个相邻Box的margin会发生重叠(塌陷),与方向无关。)
  • 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此(这说明BFC中子元素不会超出他的包含块,而position为absolute的元素可以超出他的包含块边界)
  • BFC的区域不会与float的元素区域重叠
  • 计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然

看到以上的几条约束,想想我们学习css时的几条规则

  • Block元素会扩展到与父元素同宽,所以block元素会垂直排列
  • 垂直方向上的两个相邻DIV的margin会重叠,而水平方向不会(此规则并不完全正确)
  • 浮动元素会尽量接近往左上方(或右上方)
  • 为父元素设置overflow:hidden或浮动父元素,则会包含浮动元素

BFC可以解决的问题

  1. 垂直外边距重叠问题
<style>
    .wrap {
        overflow: hidden;// 新的BFC
    }
    p {
        color: #f55;
        background: #fcc;
        width: 200px;
        line-height: 100px;
        text-align:center;
        margin: 100px;
    }
</style>
<body>
    <p>Haha</p>
    <div class="wrap">
        <p>Hehe</p>
    </div>
</body>
  1. 去除浮动
<style>
    .par {
        border: 5px solid #fcc;
        width: 300px;
        overflow: hidden; //BFC
    }
 
    .child {
        border: 5px solid #f66;
        width:100px;
        height: 100px;
        float: left;
    }
</style>
<body>
    <div class="par">
        <div class="child"></div>
        <div class="child"></div>
    </div>
</body>

  1. 自适用两列布局(float + overflow)
<style>
    body {
        width: 300px;
        position: relative;
    }
 
    .aside {
        width: 100px;
        height: 150px;
        float: left;
        background: #f66;
    }
 
    .main {
        height: 200px;
        background: #fcc;
        overflow: hidden; //BFC,BFC的区域不会与float元素重叠,否则会重叠,所以加它,变成BFC
    }
</style>
<body>
    <div class="aside"></div>
    <div class="main"></div>
</body>
 <style> 
    html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
    .left{
      background:pink;
      float: left;
      width:180px;
    }
    .center{
      background:lightyellow;
      overflow:hidden;
      
    }
    .right{
      background: lightblue;
      width:180px;
      float:right;
    }
  </style> 
  
  
</head> 

<body class="claro"> 
  <div class="container">
    <div class="left">
    左边
      <pre>
  .left{
    background:pink;
    float: left; //BFC
    width:180px;
  }
      </pre>
    </div>
    <div class="right">
    右边
       <pre>
  .right{
    background:lightblue;
    width:180px;
    float:right; //BFC
  }
      </pre>
    </div>
    <div class="center">
    中间
    <pre>
  .center{
    background:lightyellow;
    overflow:hidden;  //BFC
    height:116px;
  }
      </pre>
    </div>
  </div>
  根据BFC的区域不会与float元素重叠
  
  这种规则的特点实现左右两栏宽度固定,中间栏可以根据浏览器宽度自适应。

参考链接 github.com/zuopf769/no…