BFC是什么?
BFC(Block Formatting Context)中文直译就是‘块级格式上下文’,它是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。
通俗点说,BFC是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子内部的元素无论如何翻江倒海,都不会影响到外部。转换为BFC的理解则是:BFC中的元素的布局是不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。)并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。
BFC的产生条件
- overflow不为visible;
- 浮动(float样式不为none );
- 绝对定位(position样式为absolue或者fixed );
- display为inline-block / table-cell / table-caption / flex / table-flex;
BFC特性(作用)
-
在BFC中,内部的Box会在垂直方向,一个接一个地放置;
-
Box垂直方向的距离由margin决定,同一个BFC下相邻两个Box的margin会发生重叠;
-
在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘),即使存在浮动也是如此。
- 即不会发生margin穿透
-
形成了BFC的区域不会与float box重叠(可阻止因浮动元素引发的文字环绕现象);
-
计算BFC高度时,浮动元素也参与计算(BFC会确切包含浮动的子元素,即闭合浮动)。
-
原本浮动元素应该是脱离文档流的,但BFC中会计算其高度。
综上特性所述,BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
BFC特性的一些应用
-
实现自适应两栏布局
应用了“BFC的区域不会与float box重叠”的特性;一边浮动,另一边自适应的部分形成BFC,那么两者就不会重叠,避免了出现文字环绕及类似情形。 -
解决父元素高度塌陷(也就是闭合内部浮动 )
应用了“计算BFC高度时,浮动元素也参与计算在内”的特性; -
解决垂直方向上兄弟元素的margin重叠
应用了“属于同一个BFC的两个相邻Boc的margin会发生重叠”的特性。意味着如果相邻兄弟元素不属于同一个BFC,就不会发生margin重叠了;
BFC特性应用实例演示
实现自适应两栏布局
代码:
<style type="text/css"> .container { width: 500px; } .left { width: 100px; height: 150px; background-color: #B3D1C1; float: left; } .right { height: 200px; background-color: #A694C1; /*把.right这个自适应预算变成BFC, 避免与.left这个有float属性的元素重叠;*/ **overflow: hidden;** } </style> <body> <div class="container"> <div class="left">left</div> <div class="right">right</div> </div> </body>
这里不能通过设置float样式的方式把right变为BFC,因为float有收缩、紧密排列的特性,而right又没有固定宽度,设置float属性后,right就会收缩不见。
解决父元素高度塌陷(闭合内部浮动 )
高度塌陷产生原因:父元素未设置固定高度,完全由子元素高度撑开;当子元素float之后脱离了文档流,父元素内部没有支撑,造成高度塌陷。
解决:给塌陷的父元素添加overflow:hidden / auto使其变为BFC。
代码:
<style> .container { width: 300px; border: 1px solid #999; background-color: #DBD9B7; /*使父元素变为BFC,解决高度塌陷*/ overflow: hidden; } .son { width: 100px; height: 100px; background-color: #E67B85; /*会造成高度塌陷*/ float: left; } </style> <body> <div class="container">container <div class="son">son</div> </div> </body>
解决垂直方向上兄弟元素的margin重叠
代码:
<style> p { width: 200px; height: 100px; background-color: #fcc; margin: 25px; } .wrap { /*p外面包裹一层,并按如下设置, 形成一个单独的BFC*/ overflow: hidden; } </style> <body> <div class="wrap"> <p class="a">a</p> </div> <p class="b">b</p> </body>
触发BFC的属性(方法)与自适应布局面面观
- float:left。动元素本身BFC化,然而浮动元素有破坏性和包裹性,失去了元素本身的流体自适应性,因此,无法用来实现自动填满容器的自适应布局。不过,其因兼容性还算良好。
- position:absolute。脱离文档流严重,不建议使用。
- overflow:hidden。元素BFC本身块状元素的流体特性仍可比较完好得保留。不足之处是如果内容过多,可能会被裁剪。
- display:inline-blockl。display:inline-block会让元素尺寸包裹收缩,完全就不是我们想要的block水平的流动特性。唉,只能是一声叹气一枪毙掉的命!然而,峰回路转,世事难料。大家应该知道,IE6/IE7浏览器下,block水平的元素设置display:inline-block元素还是block水平,也就是还是会自适应容器的可用宽度显示。
- display:table-cell。让元素表现得像单元格一样,IE8+以上浏览器才支持。跟display:inline-block一样,会跟随内部元素的宽度显示,看样子也是不合适的命。但是,单元格有个非常神奇的特性,就是你宽度值设置地再大,实际宽度也不会超过表格容器的宽度。因此,如果我们把display:table-cell这个BFC元素宽度设置很大,比方说3000像素。那其实就跟block水平元素自动适应容器空间效果一模一样了。
- 剩下的基本一无是处,就不展开了。
综上总结,能担任自适应布局的方法也就是:
- overflow:auto / hidden(id7+)
- display:inline-block(ie6、ie7)
- display:table-cell(ie8+)
而由于overflow有剪裁和出现滚动条等隐患,不适合作为整站通用类,于是,最后,类似清除浮动的通用类语句:
.clearfix {
*zoom: 1;
}
.clearfix:after {
content: ''; display: table; clear: both;
}
两栏或多栏自适应布局的通用类语句是(block标签需配合浮动):
.cell {
display: table-cell; 9999px;
*display: inline-block; * auto;
}