本欲写一篇关于清除浮动的文章,结果结识了BFC(Block Formatting Context:块级格式化上下文),随着对BFC的深入了解,我发现我竟喜新厌旧抛弃了清除浮动~
一、什么是BFC(Block Formatting Context)
1、在W3C及众博友的介绍下,BFC逐渐揭开其面纱:
BFC:在一些情况下盒子被触发的一种特殊状态。触发后会使盒子有特异的表现,对,就是下面这感觉
总体的说,BFC 的触发条件有如下几种情况:
- 根元素
- float != none
- overflow != visible
- position != static、relative
- display == table-cell 、table-caption、inline-block、flex、inline-flex
2、接下来BFC出现了,她又会带来什么样的效应呢:
- BFC内部盒子的排列方式:
In a block formatting context, each box's left outer edge touches the left edge of the containing block。
每个元素的 left outer edge 与包含块的 left edge 相接触,即使存在浮动也是如此。
left outer edge 与 left edge:
- 盒子间距的计算方式:
同一个BFC中:两个相邻子Box的margin会发生重叠。
而不同的BFC中:两个相邻的Box的margin不会发生重叠。
- BFC的高度为内部盒子高度之和:
BFC的高度为内部盒子的高度之和,浮动元素也参与计算(作用:清除浮动)。
- 与外部盒子的关系:
BFC的区域不会与float box重叠。
二、进一步了解BFC的规则
1、BFC内部盒子的排列方式
a、内部的Box会在垂直方向,一个接一个地放置。
块级元素,未浮动会在垂直方向一个接一个放置。
b、每个元素的 left outer edge 与包含块的 left edge 相接触,即使存在浮动也是如此。
在W3C文档中对margin edge 和 content edge 做出解释,从解释可看出 margin edge 与 outer edge 是对应的,content edge 和 inner edge 是对应的。其中比较有争议的是 left edge 到底是 content edge 还是 border edge。故而做如下实验:
<style> .bfc{ overflow:hidden; background:rgb(219, 154, 154); width:300px; height:100px; border:20px dotted black; } .son{ background:rgb(218, 41, 41); float:left; } </style> <body> <div class="bfc"> <div class="son">子Box</div> </div> <body>
在上述代码基础上给外部盒子加上一个“padding:30px”后结果如下:
所以说,其中的 left edge 指的是 content edge。
2、盒子间距的计算方式
位于不同BFC的盒子的 margin 是不会塌陷的:
<style> .bfc1{ overflow:hidden; background:rgb(219, 154, 154); width:300px; } .son{ background:rgb(218, 41, 41); margin:15px auto; } </style> <body> <div class="bfc1"> <div class="son">Box1</div> <div class="son">Box2</div> </div> </body>
上面的 Box1 和 Box2 之间的 margin 是塌陷了的,其间距只有15px,因为它们处于同一个BFC中。要想它们之间的 margin 不塌陷,只需要将其中一个盒子嵌套到另一个BFC中即可。如:
<style> .bfc1, .bf2{ overflow:hidden; background:rgb(219, 154, 154); width:300px; } .bf2{ background:blue; } .son{ background:rgb(218, 41, 41); margin:15px auto; } </style> <body> <div class="bfc1"> <div class="son">Box1</div> <div class="bfc2"> <div class="son">Box2</div> </div> </div> </body>
因为位于不同BFC的盒子的 margin 是不会塌陷的,所以这一特性主要用来防止margin重叠。可以用于阻止相邻盒子垂直方向 margin 的重叠、阻止嵌套元素的margin重叠。
3、BFC的高度
BFC的高度与内部盒子的高度有关,不管内部盒子是否浮动。这一特性也常被用来清除浮动。
<style type="text/css"> .bfc{ background:rgb(219, 154, 154); width:300px; } .son{ background:rgb(218, 41, 41); width:200px; height:3em; float:left; } </style> <body> <div class="bfc"> <div>Box1</div> <div class="son">Box2</div> </div> </body>
接下来将外部盒子转换为BFC:
.bfc{
background:rgb(219, 154, 154);
width:300px;
overflow:hidden;
}
从对比图可知又多了一种清除浮动的方法。
4、与外部盒子的关系
BFC是一个独立的容器,其内部元素与外部元素不会相互影响,BFC的区域不会与float box重叠。
<style> .box1{ float:left; width:50px; height:80px; background:rgb(218, 41, 41); } .box2{ overflow:hidden; width:200px; height:200px; background:rgb(219, 154, 154); } </style> <body> <div class="box1">Box1</div> <div class="box2">Box2</div> </body>
在没有给 Box2 设置 “overflow” 时,显式效果为:
而上面的代码的显式结果为下图,因为 Box2 被转换为BFC,BFC不与float box重叠,利用这个特性,可以设置自适应的两栏布局。
总结:
什么触发BFC:根元素、display、overflow、position、float
BFC的规则:内部------子盒子的排列方式、外部------与别的盒子不相干、BFC高度------等于内部盒子总高度、margin------不同BFC中盒子的margin不塌陷
作用:防止margin塌陷、两栏(三栏)布局、清除浮动