Clearfix—清除浮动的影响

每当使用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;
}

此时页面的表现为:

Clearfix—清除浮动的影响_第1张图片
浮动前页面效果

此时为box添加float: left,即:

#box {
    float: left;
    width: 100px;
    height: 100px;
    background-color: lightgreen;
}

则页面表现为:

Clearfix—清除浮动的影响_第2张图片
浮动后页面效果

此时可以明显地看到,在子元素box设置浮动后,父容器高度发生了“塌陷”,仅剩下内部文本的高度。

为了使得父容器的内部包含box子元素,即达到如下效果:

Clearfix—清除浮动的影响_第3张图片
闭合浮动

这样的浮动清除方式称为闭合浮动清除

为了达到闭合浮动清除的目的,在原理上通常划分为如下两种方式:

  1. 在父容器内部的末尾添加额外的元素,通过对其添加clear: both以清除浮动的影响
  2. 使父容器创建BFC或haslayout从而闭合浮动

下面将分别介绍这两种方式。

1. 在父容器内部的末尾添加额外的元素

对于第一种方式,可采取的方案为:

float

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate.

不过这样的方法会造成重复添加过多额外且无意义的

标签,不利于代码的简洁。更好的办法是使用:after伪元素:

首先为父容器添加.clearfix类:

float

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate.

随后在CSS中定义.clearfix

.clearfix:after{
    content= ""; 
    display: table;    /* 也可以设置为block */
    clear: both;      
}

这种方法的好处是通过CSS伪元素:after巧妙地在父容器内部末尾生成了元素,与添加额外的

作用一致,且使用content= ""又能让生成的元素不占用任何空间;由于通过:after伪元素生成的元素是内联元素,而clear: both需要添加到块级元素上才能发挥作用,所以还需要为生成的内容设置display: table/block

此外,这样的方法还额外使得父容器对于容器下方的外部元素而言,“看起来”具有一些BFC的的特性——即阻止容器内部元素与容器下方的外部元素发生margin重叠
假设有:

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.

则页面的效果为:

Clearfix—清除浮动的影响_第4张图片
阻止margin重叠

究其原因,其实是由于通过:after伪元素生成的元素横亘在两者之间,这样一来两个段落的margin设置其实是相对于该元素在起作用:

Clearfix—清除浮动的影响_第5张图片
通过after伪元素生成的元素位于两个段落之间

我个人喜欢把此时的父容器称为“伪BFC容器”,因为父容器并非真正创建了BFC。如此一来,如下.clearfix代码也就好理解了:

.clearfix:before,
.clearfix:after {
    content= "";
    display: table;
}

.clearfix:after {
    clear: both;
}

2. 使父容器创建BFC或haslayout

对于第二种方式,由于BFC或haslayout都能够包含容器内部的浮动元素,所以只需要使父容器创建BFC或haslayout即可。

需要注意的是,haslayout是IE6/7中的概念,而BFC则是现代浏览器(chrome,firefox,IE8等)中的概念,两者在表现上具有相似的特点。

有许多办法可以创建BFC或haslayout,因此从理论上来说,不管用什么办法只要是创建出了BFC或haslayout都能够达到闭合浮动的目的;然而通常创建BFC或haslayout的属性或多或少都具有一定的“副作用”,如float,position: absolute,display: inline-block等,因此下面我将主要列出几种副作用较小的创建BFC或haslayout的办法:

2.1 创建haslayout

haslayout只针对IE6/7浏览器,所以可以使用CSS hack来进行声明:

.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-celldisplay: 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浏览器,该属性还是无法派上用场。

总结

盘点了一些闭合浮动的清除方法,是时候做个总结啦!如果想要对闭合浮动清除的方法兼容到IE6浏览器,则有如下几种可行的方案:

方案一:

/* 兼容到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;
}

其中方案一没有创建BFC,方案二和方案三创建了BFC或haslayout.

你可能感兴趣的:(Clearfix—清除浮动的影响)