Bootstrap

BFC 清除浮动详解

BFC

BFC 即 Block Formatting Contexts (块级格式化上下文),具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。通俗一点来讲,可以把 BFC 理解为一个封闭的大子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。就像js的函数作用域一样,BFC是页面上的作用域。

1.触发BFC

只要元素满足下面任一条件即可触发 BFC 特性:

  • body 根元素
  • 浮动元素:float 除 none 以外的值
  • 绝对定位元素:position (absolute、fixed)
  • display 为 inline-block、table-cells、flex
  • overflow 除了 visible 以外的值 (hidden、auto、scroll)
    也就是脱离文档流的元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子
2.BFC特性
  • (1)同一个 BFC 下外边距会发生折叠
<style>
div{
    width: 100px;
    height: 100px;
    background: blue;
    margin: 100px;
}
</style>
<body>
    <div></div>
    <div></div>
</body>

如果我们不了解BFC的话,会认为两个div之间的距离为200px,但其实这两个div之间的距离只有100px,因为外边距发生了折叠,这是css的一种规范。

  • (2)BFC 可以包含浮动的元素(清除浮动)

这里所说的,就是上面方法四和方法五中的原理了,触发BFC后,容器将会包裹着浮动元素。在方法四五中使用了overflow属性,也就是我们上面所说的触发BFC条件中的第五条。

  • (3)BFC 可以阻止元素被浮动元素覆盖

来看下面这个例子:

<div style="height: 100px;
    width: 100px;
    float: left;
    background: blue">
    我是一个左浮动的元素
</div>
<div style="width: 200px; 
    height: 200px;
    background: #eee">
    我是一个没有设置浮动,也没有触发BFC元素
</div>

在这个例子中左浮动的元素会将其他元素覆盖,但我们并不想其他元素被覆盖,这时就可以使用BFC,给第二个元素加上overflow:hidden,即可让第二个元素不再被浮动元素所覆盖。附BFC详解地址:BFC详解地址

二.清除浮动

什么是浮动?为什么要清除?浮动就是因为有元素使用了float属性,使得元素处于半脱离文档流的状态,无法撑开父元素。来看下面这个例子

<style type="text/css">
.div1{border: 2px solid red}
.left{
    float:left;
    width:20%;
    height:200px;
    background:#DDD}
</style>
 
<body>
<div class="div1">
<div class="left">Left</div>
</div>
<body>

浮动带来的影响,无法撑开父级元素,父级元素高度为0,这显然不是我们希望看到的,所以我们要清除浮动。

1.设置父级元素的高度

这是最简单容易理解的方式,但只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题,不推荐使用。

.div1{
    border: 2px solid red;
    height:200px}
.left{
    float:left;
    width:20%;
    height:200px;
    background:#DDD}
2.结尾处加空标签clear:both

这种方法简单、代码少、浏览器支持好、不容易出现怪问题,但原理不好理解,而且如果页面浮动布局多,就要增加很多空div,让人感觉很不好,不推荐使用。关于css的clear属性大家如果不懂的话可以直接百度,both代表元素的左右都不允许出现浮动元素。

<style type="text/css">
.div1{border: 2px solid red}
.left{
    float:left;
    width:20%;
    height:200px;
    background:#DDD}
.clearfloat{clear:both}
</style>
 
<body>
<div class="div1">
<div class="left">Left</div>
<div class="clearfloat"></div>
</div>
<body>
3.父级div定义 伪类:after 和 zoom

原理类似方法2,浏览器支持好、不容易出现怪问题,大部分的网站都在用,建议使用,但代码多、不少初学者不理解原理,要两句代码结合使用才能让主流浏览器都支持。其中的{zoom:1}是兼容IE6/7的写法,IE6/7通过zoom:1可以触发hasLayout。

<style type="text/css">
.div1{border: 2px solid red}
.left{float:left;
    width:20%;
    height:200px;
    background:#DDD}
.clearfloat:after{
    display:block;
    clear:both;
    content:"";
    display:hidden;
    height:0}
.clearfloat{zoom:1}
</style>
<body>
<div class="div1 clearfloat">
<div class="left">Left</div>
</div>
<body>
4. 父级div定义 overflow:hidden

简单、代码少、浏览器支持好,不能和position配合使用,因为超出的尺寸的会被隐藏。只推荐没有使用position或对overflow:hidden理解比较深的朋友使用。这个方法与第五个方法的原理都是触发了BFC。


<style type="text/css">
.div1{
    border: 2px solid red;
    overflow:hidden}
.left{
    float:left;
    width:20%;
    height:200px;
    background:#DDD}
</style>
 
<body>
<div class="div1">
<div class="left">Left</div>
</div>
<body>

5.父级div定义 overflow:auto

简单、代码少、浏览器支持好,但内部宽高超过父级div时,会出现滚动条。不推荐使用,如果你需要出现滚动条或者确保你的代码不会出现滚动条就使用吧。

<style type="text/css">
.div1{
    border: 2px solid red;
    overflow:auto}
.left{
    float:left;
    width:20%;
    height:200px;
    background:#DDD}
</style>
 
<body>
<div class="div1">
<div class="left">Left</div>
</div>
<body>
;