2

情景:浮动的高度塌陷时,使用overflow:hidden可使父元素将浮动的子元素包含起来,解决问题。但背后的原理是什么?这就是今天要谈的BFC。

在将BFC之前需要先了解几个概念:

盒子模型(Box model):相信这个大家已经很了解了,这里就不详细说了。详见《CSS权威指南》

块级元素:

Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the 'display' property make an element block-level: 'block', 'list-item', and 'table'.

即块级元素是源文档中被格式化为块(block)的元素,或者display属性为:'block', 'list-item', and 'table'的元素。

块级盒:

Block-level boxes are boxes that participate in a block formatting context. Each block-level element generates a principal block-level box that contains descendant boxes and generated content and is also the box involved in any positioning scheme.

块级盒主要存在于BFC中,每个块级元素会产生主要的块级盒,该盒包含其子框和生成的内容,同时会受到不同定位方案的影响。

块容器盒

Except for table boxes, and replaced elements,a block-level box is also a block container box. A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes. Not all block container boxes are block-level boxes: non-replaced inline blocks and non-replaced table cells are block containers but not block-level boxes. Block-level boxes that are also block containers are called block boxes.

除了表格框和替换元素,其他的块级盒都是块容器盒,块容器盒要么只包含块级盒,要么建立一个IFC(内行格式化上下文),并不是所有的块容器盒都是块级盒:非替代inline-block和非替代table cells是块容器盒但不是块级盒。既是块级盒又是快容器盒的叫做块盒
一下是块级盒、块盒和块容器盒三者的关系
图片描述

正常流:无论是块级盒或者是行内盒在正常流都属于格式化上下文,块级盒存在于BFC,行内盒存在于IFC,所以,正常流格式化上下文中包含BFC和IFC(行内格式化上下文,另一种格式化上下文)。

概念

BFC(Block formatting contexts):顾名思义块级格式化上下文。通俗的说,它是一个独立的渲染区域,里面只有Block-level box,并规定他们的布局方式,与其他区域互不影响。

BFC的生成

  1. 根元素或其它包含它的元素

  2. 浮动 (元素的 float 不为 none)

  3. 绝对定位元素 (元素的 position 为 absolute 或 fixed)

  4. 行内块 inline-blocks (元素的 display: inline-block)

  5. 表格单元格 (元素的 display: table-cell,HTML表格单元格默认属性)

  6. 表格标题 (元素的 display: table-caption, HTML表格标题默认属性)

  7. overflow 的值不为 visible的元素

  8. 弹性盒子 flex boxes (元素的 display: flex 或 inline-flex)

BFC布局规则

  1. 内部的Box会在垂直方向,一个接一个地放置

  2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。如果相邻有一个是BFC的话,则BFC里面的子元素margin与外面的Box的margin不重叠。

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

  4. BFC的区域不会与float box重叠,常用来清除浮动和布局。

  5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

  6. 计算BFC的高度时,浮动元素也参与计算

BFC应用

1.防止margin值重叠(布局规则2)

举个例子:

<!DOCTYPE html>
<html>
<head>
    <title>BFC</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
     <div class="red"></div>
     <div class="black"></div>
</body>
</html>
body{padding:0;margin:0}
        .red{
            background:red ;
            width:200px;
            height: 200px;
            margin: 10px;          
        }

        .black{
            background:black ;
            width:200px;
            height: 200px;
            margin: 10px;
        }

结果margin重叠:
图片描述

让红色方块变成BFC后:

<!DOCTYPE html>
<html>
<head>
    <title>BFC之防止margin重叠</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
    <div class="wrap">
         <div class="red"></div>
    </div>
     <div class="black"></div>
</body>
</html>
body{padding:0;margin:0}
        .red{
            background:red ;
            width:200px;
            height: 200px;
            margin: 10px;          
        }
        .wrap{overflow: hidden;}
        .black{
            background:black ;
            width:200px;
            height: 200px;
            margin: 10px;
        }

结果margin不重叠
图片描述

2.清除浮动
父元素包含浮动子元素(全部)时,高度会出现坍塌。

<!DOCTYPE html>
<html>
<head>
    <title>BFC</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
    <div class="wrap">
         <div class="red"></div>
          <div class="black"></div>
     </div>
</body>
</html>
body{padding:0;margin:0}
        .wrap{
            width: 500px;
            border: blue solid 2px;
        }
        .red{
            border: red solid 1px;
            width:200px;
            height: 200px;
            float: left;         
        }
        
        .black{
            border: black solid 1px;
            width:200px;
            height: 200px;
            float: right;

        }

结果:图片描述

给父元素添加overflow: hidden;后父元素变成BFC,根据布局规则6,父元素会将子元素包含在内。

<!DOCTYPE html>
<html>
<head>
    <title>BFC</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
    <div class="wrap">
         <div class="red"></div>
          <div class="black"></div>
     </div>
</body>
</html>
body{padding:0;margin:0}
        .wrap{
            width: 500px;
            border: blue solid 2px;
            overflow: hidden;
        }
        .red{
            border: red solid 1px;
            width:200px;
            height: 200px;
            float: left;         
        }
        
        .black{
            border: black solid 1px;
            width:200px;
            height: 200px;
            float: right;

        }

结果图片描述

3.两栏自适应布局
如果左栏设置为浮动,右边一栏正常显示,则会将浮动会盖住右边。


![clipboard.png](/img/bVHIZZ)
l>
<html>
<head>
    <title>BFC</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
         <div class="left"></div>
          <div class="main"></div>
</body>
</html>
body{padding:0;margin:0}

        .left{
            border: red solid 1px;
            width:200px;
            height: 200px;
            float: left;         
        }
        
        .main{
            border: black solid 1px;
            width:250px;
            height: 250px;
            

        }

结果
图片描述

给main那一栏添加 overflow: hidden;后变成BFC(根据布局规则2)。

<!DOCTYPE html>
<html>
<head>
    <title>BFC</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
         <div class="left"></div>
          <div class="main"></div>
</body>
</html>
body{padding:0;margin:0}

        .left{
            border: red solid 1px;
            width:200px;
            height: 200px;
            float: left;         
        }
        
        .main{
            border: black solid 1px;
            width:250px;
            height: 250px;
            overflow: hidden;
            
        }

结果
图片描述

思考与总结

因为根元素就是一个BFC,文档中块级盒的布局规则符合BFC,所以书里面写的文档流是从上到下的排列、相邻块级之间的margin会发生重叠,浮动会自动形成block等知识点,其实在这里就能找到答案。包括清除浮动、两栏自适应布局的原理也清晰明了。因此掌握BFC原理也掌握另一种解决问题的思路。
这里有点建议就是尽量阅读官网的资料,里面的内容最准确,最权威。

以上是我粗浅的理解,如果哪里有问题,请帮忙指出,有未涉及的知识点,欢迎补充。一起学习,共同进步。

参考

https://www.w3.org/TR/2011/RE...

https://developer.mozilla.org...

http://www.yangyong.me/css2-b...


jango
47 声望2 粉丝