从几种清除浮动的方法聊到BFC
【清除浮动】
在清除浮动之前,我们总得知道为什么要清除浮动吧?看下面这段代码:
<div class="topDiv">
<div class="floatDiv">
float left
</div>
<div class="textDiv">
不知曾几何时,随着智能机的成熟发展,防水性能无形之中成为了手机的众多卖点之一。对不少亲身经历的用户而言.
</div>
</div>
<div class="bottomDiv">
27日
</div>
按正常情况下,topDiv这个盒子里放置的floatDiv和textDiv盒子本应该正常排列,但是在我们对floatDiv这个盒子加了float:left属性后,情况就发生了变化
这里我们可以看到,在floatDiv盒子添加了float属性后,整体的布局发生了改变,我们可以得知它造成的影响
- 影响了页面整体的布局
- 影响了父容器topDiv的高度,正常父元素的高度是自适应的,高度为其包含的内容总高度,而内部元素的浮动造成了父容器高度塌陷。(可以看到这里我们的topDiv盒子的高度明显发生了塌陷)
- 父容器的塌陷,影响了与父元素同级的其它元素的布局(例如上图中红色盒子同时穿插了topDiv盒子和与它同级的bottomDiv盒子,对其造成了影响
作为一名合格的前端开发人员,我们总不可能为了实现让文字环绕图片排版的功能,给甲方提交一个这样的页面吧?所以此时我们就会用到以下几种清除浮动的方法,来清除浮动对整体的影响。
【方法】
①在同级向下相邻元素上使用clear属性
很多人可能问这是啥意思啊?在这我们拿上面的例子来说明,这里说的同级相邻元素指的是在添加了浮动属性的元素的同级元素,也就是textDiv盒子上添加clear属性,下面是效果图
前提是textDiv这个盒子在floatDiv的下方,在上方则不起作用
②父元素结束标签之前插入清除浮动的“块级元素” 行内元素不行。 这里的父类元素标签指的是添加了float属性的那个元素所处的父容器,在本例子中就是在topDiv的前,放置一个块级元素,并对这块级容器的css中写入clear属性
html中
<div class="clearfix">
</div>
css中
.clearfix
{
clear:both;
}
③给父元素增加一个伪元素 在伪元素上做clear:both
本例中的父类元素是topDiv,也就是说对其添加一个伪元素,并在其内写入clear属性
.topDiv::after{
content:'.';
display: block;
height: 0;
overflow: hidden;
clear: both;
}
④ 把父容器设置成BFC容器,BFC容器效果能够把脱离文档流的元素的高度也计算到父容器里面去,以达到清除浮动的效果
.topDiv
{
overflow: hidden;
}
看到这里可能有人会问,什么是BFC容器呢?说实话我每次看到这个都联想到KFC。。。
什么是BFC?
BFC的全称是“BFC(Block Formatting Context) 块级格式化上下文”,它是w3里的一个概念,它决定了元素如何对其内容进行定位。将盒子设为BFC容器时,恰好可以抵消浮动带来的影响,但这并不意味着BFC容器就是单独用来抵消浮动影响的,只是它恰好有这种作用而已。BFC就是页面上的一个隔离的独立的容器,在计算BFC容器高度时,会把其中的浮动元素的高度也计算其内,
BFC的布局规则
1. 内部的Box会在垂直方向,一个接一个地放置。
2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。
3. 每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
4. BFC的区域不会与float box重叠。
5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
6. 计算BFC的高度时,浮动元素也参与计算。
看以下代码
主体
<div class="box">
<div class="left"></div>
<div class="right"></div>
</div>
css部分
.left
{
background:green;
border:3px solid #f31264;
width: 200px;
height: 200px;
opacity: 0.5;
float:left;
}
.right
{
background: #ef5be2;
opacity: 0.5;
border: 3px solid #f31264;
width: 400px;
min-height: 100px;
}
以上为初始状态下,仅对left盒子进行了设置float属性,此时画面是这样的
此时我们可以清楚的看到left盒子,也就是绿色那一部分,脱离了文档流,造成了父容器的高度坍塌,也就是灰色的那个盒子高度坍塌。此时我们把父容器变为BFC容器
<div class="box BFC">
此时页面效果如下
此时可看到,对父容器box设置为BFC容器后,浮动对其造成的高度塌陷影响已经消失了,它的高度包含了浮动元素的高度,也就是撑起来了。由此可以知道,BFC容器可以解决浮动带来的影响。那么除此之外?它还有其它作用么?那显然是有的,毕竟BFC的存在不是为了解决浮动问题的,只不过恰好可以有这么个效果而已。BFC容器还有另一个常用的作用,它可以解决margin的重叠问题。
BFC解决margin重叠问题
我们创建一个新的html,放入代码
.wrap
{
background: orange;
width: 100%;
height: 500px;
}
.container
{
height: 200px;
background: green;
}
.box
{
height: 100px;
background: pink;
}
此时页面效果是下面这样的
我们依次给这三个容器设置margin-top,值分别是100px,100px,50px,大家此时是不是觉得此时的效果是这样的
但其实并不是的,它此时的效果是这样的
它的整体向下移动了100px距离,这是css的一个bug,在相邻的盒子使用margin时,会取值最大的那个值实现。而将盒子设置为BFC容器可以解决这个问题
<div class="wrap BFC">
<div class="container BFC">
<div class="box BFC">
此时的页面效果便是第二张图了,也就是说设置为BFC容器后解决了margin重叠问题。
在这里我们要注意,BFC包含创建上下文元素的所有子元素,但是不包含新创建BFC的子元素的内部元素,也就是山高皇帝远。举个例子,A为一个大容器,里面装着B容器,B容器里装着C容器,此时我们将A容器设置为BFC容器,那么B和C就受A控制。但此时将A、B同时设置为BFC容器,那么C只能被B控制,A控制不了B。
如何设置BFC容器,需要什么条件?
.BFC
{
overflow: hidden;
}
我们在这里面除了塞hidden还能放什么可以达到同样效果呢?这里总结了一下
1. 用 overflow:hidden 和 overflow:auto overflow:scroll overflow:overlay 都可以创建
2. 绝对定位 (absolute、fixed)
3. 行内块级(inline-block)
4. 表格单元 (display:table-cell)
5. 弹性盒子 (flex、inline-flex)
除了以上之外,还有一种很有意思的方法。比如A中放了B盒子,A没设置高度,此时B设置float属性,那么A会高度坍塌。此时我们可以把A也设置为float,与B一起脱离文档流,那么此时A又会被B撑开,也能清除浮动带来的影响。