css 清除浮动 clearfix

在学习做一个显示图片的网页的时候,使用的方法是一个div父框架,包含几个子div,布局需要,子div全部设置成了左浮动,然后在通过浏览器看父div的高度一直是0,然后看一个教程说是这种情况下需要清除浮动,用的clearfix方法,当时不太理解这个方法,然后查了资料之后明白了这儿有很大的学问呢。

查看的资料:http://www.jb51.net/css/67471.html 《浮动从何而来 我们为何要清除浮动 清除浮动的原理是什么》讲的很精确深入

接下来主要记下自己的收获理解:

1、浮动(float)

浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。
由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。

我所理解的浮动脱离文档流,可以看成两个上下放着的相框,下边那个相框是文档流,里面放的相片可以布局但是必须和这个相框在一个平面,上面的相框用来存放浮动框,比较自由方便布局,如果从俯视的角度看,他们的布局效果在同一个平面。(理解方式不一定对,只是更形象的自我理解)

2、出现问题

从相框角度去思考的话,一种情况就是下面的相框(文档流)如果高度比较小甚至是0,二上面的相框(浮动框)高度比下面的高,就出现了问题,称之为“高度塌陷”,这种情况对我们的布局,以及父div的高度等等有很大影响。

3、解决方案

上面链接的文章中提到其中解决方法,其中前六种不够理想,具体如下(直接使用原文讲解):

1)添加额外标签
通过在浮动元素末尾添加一个空的标签例如

,其他标签br等亦可。

<div class="warp" id="float1"> 
<h2>1)添加额外标签</h2> 
<div class="main left">.main{float:left;}</div> 
<div class="side left">.side{float:right;}</div> 
<div style="clear:both;"></div> 
</div> 
<div class="footer">.footer</div> 

优点:通俗易懂,容易掌握
缺点:可以想象通过此方法,会添加多少无意义的空标签,有违结构与表现的分离,在后期维护中将是噩梦,这是坚决不能忍受的。

2)使用 br标签和其自身的 html属性
这个方法有些小众,br 有 clear=“all | left | right | none”

<div class="warp" id="float2"> 
<h2>2)使用 br标签和其自身的 html属性</h2> 
<div class="main left">.main{float:left;}</div> 
<div class="side left">.side{float:right;}</div> 
<br clear="all" /> 
</div> 
<div class="footer">.footer</div> 

优点:比空标签方式语义稍强,代码量较少
缺点:同样有违结构与表现的分离,不推荐使用

3)父元素设置 overflow:hidden
通过设置父元素overflow值设置为hidden;在IE6中还需要触发 hasLayout ,例如 zoom:1;

<div class="warp" id="float3" style="overflow:hidden; *zoom:1;"> 
<h2>3)父元素设置 overflow </h2> 
<div class="main left">.main{float:left;}</div> 
<div class="side left">.side{float:right;}</div> 
</div> 
<div class="footer">.footer</div>

优点:不存在结构和语义化问题,代码量极少
缺点:内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素;04年POPO就发现overflow:hidden会导致中键失效,这是我作为一个多标签浏览控所不能接受的。所以还是不要使用了
4)父元素设置 overflow:auto 属性
同样IE6需要触发hasLayout,演示和3差不多
优点:不存在结构和语义化问题,代码量极少
缺点:多个嵌套后,firefox某些情况会造成内容全选;IE中 mouseover 造成宽度改变时会出现最外层模块有滚动条等,firefox早期版本会无故产生focus等, 请看 嗷嗷的 Demo ,不要使用

方案3、4通过overflow闭合浮动,实际上已经创建了新的
块级格式化上下文,这将导致其布局和相对于浮动的行为等发生一系列的变化,清除浮动只不过是一系列变化中的一个作用而已。所以为了闭合浮动去改变全局特性,这是不明智的,带来的风险就是一系列的bug,比如firefox
早期版本产生
focus,截断绝对定位的层等等。始终要明白,如果单单只是需要闭合浮动,overflow就不要使用,而不是某些文章所说的“慎用”。

5)父元素也设置浮动
优点:不存在结构和语义化问题,代码量极少
缺点:使得与父元素相邻的元素的布局会受到影响,不可能一直浮动到body,不推荐使用
6)父元素设置display:table
优点:结构语义化完全正确,代码量极少
缺点:盒模型属性已经改变,由此造成的一系列问题,得不偿失,不推荐使用

上面几种方法主要是从添加一个空标签或者在父元素中设置overflow或浮动等方式,都有很大缺陷。
第七种方法也是目前最常用的比较好的方法:使用:after 伪元素
(7)使用:after 伪元素

需要注意的是
:after是伪元素(Pseudo-Element),不是伪类(某些CSS手册里面称之为“伪对象”),很多清除浮动大全之类的文章都称之为伪类,不过csser要严谨一点,这是一种态度。
由于IE6-7不支持:after,使用 zoom:1触发 hasLayout。 该方法源自于: How To Clear Floats
Without Structural Markup

<style type="text/css"> 
.clearfix:after { 
content: "."; 
display: block; 
height: 0; 
clear: both; 
visibility: hidden; 
} 
.clearfix {display: inline-block;} /* for IE/Mac */ 
</style> 
<!--[if IE]> <style type="text/css"> 
.clearfix {zoom: 1;/* triggers hasLayout */ 
display: block;/* resets display for IE/Win */} 
</style> 
<![endif]--> 

鉴于 IE/Mac的市场占有率极低,我们直接忽略掉,最后精简的代码如下:

.clearfix:after {content:"."; display:block; height:0; visibility:hidden; clear:both; } 
.clearfix { *zoom:1; } 

优点:结构和语义化完全正确,代码量居中
缺点:复用方式不当会造成代码量增加

通过对比,我们不难发现,其实以上列举的方法,无非有两类: 其一,通过在浮动元素的末尾添加一个空元素,设置
clear:both属性,after伪元素其实也是通过 content 在元素的后面生成了内容为一个点的块级元素; 其二,通过设置父元素
overflow 或者display:table 属性来闭合浮动,

之后上面链接的文章中讲了关于BFC(Block formatting contexts 块级格式化上下文),讲解清楚浮动的原理,我对BFC理解的还不够深,有兴趣可以通过链接去看。

四、方法优化
原文中提到两种方法来对第七种方法进行优化

上面已经列举了7种闭合浮动的方法,通过BFC原理,我们发现其实更多的:display:table-
cell,display:inline-block等只要触发了BFC的属性值都可以闭合浮动。从各个方面比较,after伪元素闭合浮动无疑是相对比较好的解决方案了,下面详细说说该方法。

.clearfix:after {content:"."; display:block; height:0; visibility:hidden; clear:both; } 
.clearfix { *zoom:1; } 

1) display:block 使生成的元素以块级元素显示,占满剩余空间; 2) height:0 避免生成内容破坏原有布局的高度。
3) visibility:hidden 使生成的内容不可见,并允许可能被生成内容盖住的内容可以进行点击和交互; 4)通过
content:”.”生成内容作为最后一个元素,至于content里面是点还是其他都是可以的,例如oocss里面就有经典的
content:”XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”,有些版本可能content
里面内容为空,一丝冰凉是不推荐这样做的,firefox直到7.0 content:”” 仍然会产生额外的空隙; 5)zoom:1 触发IE
hasLayout。

通过分析发现,除了clear:both用来清除浮动的,其他代码无非都是为了隐藏掉content生成的内容,这也就是其他版本的闭合浮动为什么会有font-size:0,line-height:0。

优化方案一: 用U+200B 代替content里面的点

相对于空标签闭合浮动的方法代码似乎还是有些冗余,通过查询发现Unicode字符里有一个“零宽度空格”,也就是U+200B
,这个字符本身是不可见的,所以我们完全可以省略掉 visibility:hidden了

.clearfix:after {content:"\200B"; display:block; height:0; clear:both; } 
.clearfix { *zoom:1; }. 

缺点:Unicode字符不适合内嵌CSS的GB2312编码的页面。

优化方案二:

由Nicolas Gallagher 大湿提出来的,原文:A new micro clearfix
hack,该方法也不存在firefox中空隙的问题。

/* For modern browsers */ 
.cf:before,.cf:after { 
content:""; 
display:table; 
} 
.cf:after { clear:both; }/* For IE 6/7 (trigger hasLayout) */ 
.cf { zoom:1; } 

原文提到这种方法需要实践确定有没有什么问题,我用这种方法在我的网页里效果和方法7一样,能够清楚浮动,但是有没有什么缺陷,由于我本身就是个菜鸟,没有看出来,可能需要大牛进一步鉴定了

需要注意的是: 上面的方法用到了
:before伪元素,很多人对这个有些迷惑,到底我什么时候需要用before呢?为什么方案一没有呢?其实它是用来处理margin边距重叠的,由于内部元素
float 创建了BFC,导致内部元素的margin-top和 上一个盒子的margin-bottom
发生叠加。如果这不是你所希望的,那么就可以加上before,如果只是单纯的闭合浮动,after就够了!并不是如同大漠《Clear
Float》一文所说的:但只使用clearfix:after时在跨浏览器兼容问题会存在一个垂直边距叠加的bug,这不是bug,是BFC应该有的特性。

总之,方法7应该是目前清楚浮动最常用最普遍比较好的一种方法,我通过方法7已经顺利清楚浮动,父div框架在浏览器中的调试已经能够看到高度(里面浮动的子div的高度)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章