每当使用float: left/right
时,在大部分情况下都将不可避免地需要清除浮动造成的影响。对于清除一般的浮动而言,在浮动元素下方的元素上添加clear: left/right/both
声明即可。
然而,有一类浮动清除略显特殊,即闭合浮动清除。由于浮动具有“破坏性”——被设置为浮动的元素会被移出正常流(normal flow),这就会使得包含浮动元素的容器表现为高度“塌陷”。为了说明这个问题,假设有如下HTML代码:
float
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate.
为其添加基础CSS样式:
#container {
background-color: lightskyblue;
}
#box {
width: 100px;
height: 100px;
background-color: lightgreen;
}
此时页面的表现为:
此时为box
添加float: left
,即:
#box {
float: left;
width: 100px;
height: 100px;
background-color: lightgreen;
}
则页面表现为:
此时可以明显地看到,在子元素box
设置浮动后,父容器高度发生了“塌陷”,仅剩下内部文本的高度。
为了使得父容器的内部包含box
子元素,即达到如下效果:
这样的浮动清除方式称为闭合浮动清除。
为了达到闭合浮动清除的目的,在原理上通常划分为如下两种方式:
- 在父容器内部的末尾添加额外的元素,通过对其添加
clear: both
以清除浮动的影响。 - 使父容器创建BFC或haslayout从而闭合浮动。
下面将分别介绍这两种方式。
1. 在父容器内部的末尾添加额外的元素
对于第一种方式,可采取的方案为:
float
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate.
不过这样的方法会造成重复添加过多额外且无意义的 首先为父容器添加 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. 随后在CSS中定义 这种方法的好处是通过CSS伪元素 此外,这样的方法还额外使得父容器对于容器下方的外部元素而言,“看起来”具有一些BFC的的特性——即阻止容器内部元素与容器下方的外部元素发生margin重叠: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. 则页面的效果为: 究其原因,其实是由于通过 我个人喜欢把此时的父容器称为“伪BFC容器”,因为父容器并非真正创建了BFC。如此一来,如下 对于第二种方式,由于BFC或haslayout都能够包含容器内部的浮动元素,所以只需要使父容器创建BFC或haslayout即可。 需要注意的是,haslayout是IE6/7中的概念,而BFC则是现代浏览器(chrome,firefox,IE8等)中的概念,两者在表现上具有相似的特点。 有许多办法可以创建BFC或haslayout,因此从理论上来说,不管用什么办法只要是创建出了BFC或haslayout都能够达到闭合浮动的目的;然而通常创建BFC或haslayout的属性或多或少都具有一定的“副作用”,如 haslayout只针对IE6/7浏览器,所以可以使用CSS hack来进行声明: 可以在父容器中添加 对父容器使用 其实 盘点了一些闭合浮动的清除方法,是时候做个总结啦!如果想要对闭合浮动清除的方法兼容到IE6浏览器,则有如下几种可行的方案: 其中方案一没有创建BFC,方案二和方案三创建了BFC或haslayout.:after
伪元素:
.clearfix
类:.clearfix
:.clearfix:after{
content= "";
display: table; /* 也可以设置为block */
clear: both;
}
:after
巧妙地在父容器内部末尾生成了元素,与添加额外的content= ""
又能让生成的元素不占用任何空间;由于通过:after
伪元素生成的元素是内联元素,而clear: both
需要添加到块级元素上才能发挥作用,所以还需要为生成的内容设置display: table/block
。
假设有::after
伪元素生成的元素横亘在两者之间,这样一来两个段落的margin设置其实是相对于该元素在起作用:.clearfix
代码也就好理解了:.clearfix:before,
.clearfix:after {
content= "";
display: table;
}
.clearfix:after {
clear: both;
}
2. 使父容器创建BFC或haslayout
float
,position: absolute
,display: inline-block
等,因此下面我将主要列出几种副作用较小的创建BFC或haslayout的办法:2.1 创建haslayout
.clearfix {
*zoom: 1;
}
2.2 创建BFC
1. 使用overflow
overflow: auto/hidden
:#container {
overflow: auto; /* 也可以使用hidden */
}
overflow: auto/hidden
的BFC特性从IE7浏览器就开始支持,唯一的问题就是当容器内部的元素超出容器尺寸时,会发生隐藏或出现滚动条的情况,如果能确保上述情况不发生,那么使用overflow
是很舒服的~2. 使用display: table-cell
#container {
display: table-cell;
width: 9999px;
}
display: table-cell
也可以创建BFC。不过,由于display: table-cell
和display: inline-block
一样都具有“包裹性”,所以会造成父容器宽度缩小,然而display: table-cell
有一个神奇的特性,那就是在显式设置其宽度时,无论把宽度值设置得再大,实际宽度也不会超过父元素的宽度,因此为了改变父容器的“包裹性”,可以添加width: 9999px
。最后,display: table-cell
适用于IE8及以上版本浏览器。3. 使用display: flow-root
#container {
display: flow-root;
}
display: flow-root
就是BFC的代名词,它可以在不产生任何副作用的情况下创建出BFC,还能保留元素原有的特性(如流体自适应性)。虽说好是好,但是由于这个属性比较新,目前只有主流的现代浏览器(chrome,firefox,opera)才支持,因此如果想要兼容IE浏览器,该属性还是无法派上用场。总结
方案一:
/* 兼容到IE8 */
.clearfix:before,
.clearfix:after {
content= "";
display: table; /* 也可以设置为block */
}
.clearfix:after {
clear: both;
}
/* 兼容IE6/7 */
.clearfix {
*zoom: 1;
}
方案二:
/* 兼容到IE7 */
#container {
overflow: auto; /* 也可以使用hidden */
}
/* 兼容IE6 */
.clearfix {
*zoom: 1;
}
方案三:
#container {
display: table-cell; /* 兼容到IE8 */
width: 9999px;
}
/* 兼容IE6/7 */
.clearfix {
*zoom: 1;
}