浮动问题和清除浮动的方法

【问题】

当一个元素是浮动的,如果没有关闭浮动时,其父元素不会包含这个浮动元素,因为此时浮动元素从文档流中脱离(float的影响具体可读《float深入剖析》一文)。如下:

<!doctype html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css">
.out{background:blue;width:200px;}
.in1{background:#ccc;width:50px;height:50px;float:left;}
.in2{background:red;width:50px;height:50px;float:left;}
</style>
</head>
<body>
    <div class="out">out
        <div class="in1">in1</div>
        <div class="in2">in2</div>        
    </div>
</body>
</html>

out作为in1和in2的父元素,却不能将自身撑开容纳二者(in1和in2高都是50px,至少撑开50px,而现在却只有18px),效果如下图。是因为in1和in2都加了向左浮动的样式出现了浮动问题。这就需要清除浮动让子元素回归正常文档流。

【清除浮动的方法】

1.给父元素out也加上一个浮动

<style type="text/css">
.out{background:blue;width:200px;float:left;}
.in1{background:#ccc;width:50px;height:50px;float:left;}
.in2{background:red;width:50px;height:50px;float:left;}
</style>

在w3cplus网站里《CSS的Float之一》一文中提到还需给父元素设一个大于“50%”宽度,这有待研究。

优点:不存在结构和语义化问题。

缺点:与父元素相邻的元素的布局会受到影响。不推荐。

2.为浮动的子元素清除浮动。在in2后面增加一个空的div用于清除浮动,在CSS中使用clear属性,同时应将这个空div的高与行高设为0(其实不太懂为什么要把height和line-height都设为0,在w3cplus里《CSS的Float之一》一文中有提到,好像是为了不让ie具有一定的空间,最好再加上font-size=0;。可是在chrome下就算不设置效果也一样,这个有待考究)。其实我觉得叫做“关闭浮动”比较合适,因为你又想用浮动,然后又要除掉它,有点矛盾。用完浮动后把它关闭,这样理解比较合理。

<!doctype html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css">
.out{background:blue;width:200px;}
.in1{background:#ccc;width:50px;height:50px;float:left;}
.in2{background:red;width:50px;height:50px;float:left;}
.clear{clear:left;height:0;line-height:0;}
</style>
</head>
<body>
    <div class="out">out
        <div class="in1">in1</div>
        <div class="in2">in2</div>    
        <div class="clear"></div>    
    </div>
</body>
</html>

out的高度变成50px,是由in1,in2撑开了:

缺点:添加了无意义的空标签,有违结构与表现的分离,后期维护难。不推荐。

3.为父元素设置overflow属性,设置值为auto或hidden都行,不过不能是visible,否则无法清除浮动。关于前两者区别,在《Clear Float》一文中提到auto对seo比较友好,hidden对seo不是太友好。

.out{
  background:blue;width:200px;
  overflow:auto;/*或overflow:hidden;*/
  zoom: 1;/*在IE下触发其layout,也要以使用_height:1%来代替zoom*/
}

优点:不存在结构和语义化问题。

缺点:内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素。

4.使用clearfix的方法。以下是来自w3cplus网《Clear Float》一文的说法:

利用:after和:before来在元素内部插入两个元素块,从面达到清除浮动的效果。其实现原理类似于clear:both方法,只是区别在于:clear在html插入一个div.clear标签,而clearfix利用其伪类clear:fix在元素内部增加一个类似于div.clear的效果。

只需给包含浮动元素的父元素一个clearfix的class,再对其设置相关样式,如下所示:

<!doctype html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css">
.out{background:blue;width:200px;}
.in1{background:#ccc;width:50px;height:50px;float:left;}
.in2{background:red;width:50px;height:50px;float:left;}
.clearfix:before,
.clearfix:after{
    content: "."; 
    display: block; 
    height: 0; 
    visibility: hidden;}
 .clearfix:after {clear: both;}
.clearfix{zoom:1;/*IE<8*/}
</style> </head> <body> <div class="out clearfix">out <div class="in1">in1</div> <div class="in2">in2</div> </div> </body> </html>

其实只使用clearfix:after就可以达到清除浮动的效果,但只使用clearfix:after时在跨浏览器兼容问题会存在一个垂直边距叠加的bug……所以为了让浏览器兼容这个clearfix的清除浮动,在原来的基础上加止clearfix:before,这样就解决了跨浏览器的兼容问题。

以上是该文作者大漠所说的。而在《那些年我们一起清除过的浮动》一文中作者认为:

clearfix:before是用来处理margin边距重叠的,由于内部元素 float 创建了BFC,导致内部元素的margin-top和 上一个盒子的margin-bottom 发生叠加。如果这不是你所希望的,那么就可以加上before,如果只是单纯的闭合浮动,after就够了!并不是如同大漠《Clear Float》一文所说的:但只使用clearfix:after时在跨浏览器兼容问题会存在一个垂直边距叠加的bug,这不是bug,是BFC应该有的特性。

 5、在《那些年我们一起清除过的浮动》一文中还提到了在父元素设置display:table;的方法。还有在浮动元素后添加<br>标签并设置属性clear:all;的方法。

  文后还有对为什么overflow:hidden;可以清除浮动问题的探究,可以学习。截取一段该文对使用伪元素清除浮动各行代码的解释学习学习,因为我不懂。

.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。

posted on 2017-01-16 00:57  jettyhuang  阅读(429)  评论(0编辑  收藏  举报

导航