BFC详解

【主要内容】

用法规则,如何触发 BFC 以及 BFC 的一些用处(如清浮动,防止 margin 重叠等)

 

【简介】

      BFC(Block Formatting Context块级格式化上下文),它规定了内部的块级元素的布局方式,默认情况下只有根元素(即body)一个块级上下文。通俗理解为页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素;外面的元素也不会影响到容器里面的子元素

 

1、BFC布局规则

①内部的块级元素会在垂直方向,一个接一个地放置;

②块级元素垂直方向的距离由margin决定。属于同一个BFC的两个相邻的块级元素会发生margin合并,不属于同一个BFC的两个相邻的块级元素不会发生margin合并;

③每个元素的margin box的左边,与包含border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此;

④BFC的区域不会与float box重叠(所以可以解决浮动造成的重叠覆盖问题);

⑤BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素;外面的元素也不会影响到容器里面的子元素;

⑥计算BFC的高度时,浮动元素也参与计算(所以可以消除浮动)

 

2、创建一个BFC

首先我们要知道怎样创建BFC。一个BFC可以被显式触发,只需满足以下条件之一:

float的值不为none;

overflow的值不为visible;

position的值为fixed / absolute;

display的值为table-cell / table-caption / inline-block / flex / inline-flex

 

3、BFC的应用

(1)消除margin合并

      在之前文章里我写过相邻兄弟元素、父元素与第一个和最后一个子元素、空块元素的margin合并情况。那么对于发生margin合并的元素,我们怎样消除margin合并?

      对于父子元素,我们可以通过设置padding、border、inline content、height、min-height、max-height等属性来消除;但是相邻的兄弟元素之间必出现margin合并,这时如果想要消除margin合并,又该怎么办?

      我们首先要搞清楚为什么会发生margin合并

这些元素(包括兄弟、父子元素等)之间之所以会发生margin合并,是因为它们属于同一个BFC。所以,我们就知道怎么办了,只要让它们不属于同一个BFC不就可以了?

我们来举个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>css1</title>
    <style type="text/css">
        body {
            margin: 0;
            padding: 0;
        }
        .bro1 {
            width: 300px;
            height: 200px;
            background: #ddd;
            margin-bottom: 30px;
        }
        .bro2 {
            width: 200px;
            height: 100px;
            background: pink;
            margin-top: 20px;
        }
    </style>
</head>
<body>
<div class='bro1'></div>
<div class='bro2'></div>
</body>
</html>

   结果显示为:30px;即合并后取了较大值----bor1的下外边距

【方案】

  现在我们给.bro1新建一个BFC,并添加 overflow:hidden;

<div style="overflow:hidden">
    <div class='bro1'></div>
  </div>

 至此,margin合并消除了!

(2)包含浮动子元素

   这也是我们的主要议题——为什么"overflow:hidden"能清除浮动的影响?

   我们经常会在父元素里设置某个子元素浮动。浮动后,子元素脱离了文档流,使得父元素无法包住这个浮动的子元素。

   通常在父元素上设置一个clearfix的伪元素来清除浮动;同样,我们可以利用BFC可以包含浮动这一特性来清除浮动,例子已经在之前讲过

   我们对之前的例子作一个分析:当给父级设置"overflow:hidden"时,实际上创建了一个超级属性BFC,此超级属性反过来决定了"height:auto"是如何计算的

   因为在“BFC布局规则”中提到:计算BFC的高度时,浮动元素也参与计算。因此,父元素在计算其高度时,加入了浮动元素的高度,“顺便”达成了清除浮动的目标,所以父元素就包裹住了子元素

(3)解决由于浮动造成的重叠覆盖问题

     一般情况下,浮动元素会脱离文档流,即不占位置。它的兄弟元素会与它在左上角重叠。但是如果两个相邻元素都设置了浮动,那么意味着它们都是以BFC的规则渲染,根据上述第四条规则,BFC区域不会相互重叠,所以便能理解为什么设置浮动后元素能独占空间了

这里举个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>css1</title>
    <style type="text/css">
        body {
            margin: 0;
            padding: 0;
        }
        .bro1 {
            width: 200px;
            height: 200px;
            background: #ddd;
            float: left;
        }
        .bro2 {
            width: 200px;
            height: 200px;
            background: pink;
            /*display: inline-block, table-cell, table-caption, flex, inline-flex;*/
            /*overflow: hidden;*/
        }
    </style>
</head>
<body>
<div class='bro1'></div>
<div class='bro2'></div>
</body>
</html>
  给元素添加以下属性,即可激活BFC(块级格式化上下文)

  float属性不为none;position为absolute或fixed;display为inline-block, table-cell, table-caption, flex, inline-flex;overflow不为visible

 

 

【注意】

   ①除了设置"overflow:hidden",我们还可以设置"display:inline-block"、"position:absolute"、"float:left"等方式来创建一个BFC,从而达到包裹浮动子元素的效果(具体使用哪种方法要看项目需求)

   ②IE6、7不支持伪元素,在IE6、7内有个hasLayout的概念,当元素的hasLayout属性值为true的时候会达到和BFC类似的效果。zoom:1 在IE6、7可以使hasLayout为true,所以如果清除浮动要兼容IE6、7,需要加上 zoom:1

    ③IE7及以下版本不支持BFC的,但有私有属性haslayout,于是我们可以通过触发元素的haslayout来达成bfc的相似效果

 

 

 

 【拓展】

 针对上面BFC布局规则第四条

 ④BFC的区域不会与float box重叠(所以可以解决浮动造成的重叠覆盖问题);

这里详细介绍下:

<div>元素A</div>
<div>元素B</div>

 代码效果如图:

 

 当你元素A添加float属性后,元素A脱离文档流

正常情况下,后面元素B会与前面的元素A重叠(因为float导致A元素脱离文档流不再占据原来的位置,后面元素会占据前面的位置,如图)

 

元素产生BFC的原因{

  根元素

  float属性不为none

  position为absolute或fixed

  display为inline-block, table-cell, table-caption, flex, inline-flex

  overflow不为visible

}

这个时候,我们任意选取上面一种原因加给元素B,比如加上overflow:hidden;

于是元素B 产生了BFC效果导致元素B收缩,不在占据元素A位置,如图

 

 

 

 

 

.

猜你喜欢

转载自570109268.iteye.com/blog/2410183
BFC