CSS 清除浮动

浮动的原理

float属性定义元素在哪个方向浮动。以往这个属性总应用于图像,使文本围绕在图像周围,不过在 CSS 中,任何元素都可以浮动。浮动元素会生成一个块级框,而不论它本身是何种元素。float:right|left|none|inherit

浮动的框可以向左或向右移动,直到它的外边缘碰到包含它的框或另一个浮动块的边框为止。由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。浮动框旁边的行框被缩短,从而给浮动框留出空间,行框围绕浮动框。因此,创建浮动框可以使文本围绕图像。当一个元素浮动之后,不会影响到块级框的布局而只会影响内联框(通常是文本)的排列。

浮动出现的意义其实只是用来让文字环绕图片。图片本身一个inline boxes,图片与文字基线对齐,图片与文字在同一行上。浮动破坏了正常的line boxes,由于浮动元素没有了inline boxes,没有了inline boxes高度,才能让其他inline boxes元素重新整合,环绕浮动元素排列。“包裹与破坏”(inlinebox叠加成linebox的高度,行框与行内框(见印象笔记))

顾名思义,就是漂浮于普通流之上,像浮云一样,但是只能左右浮动。给元素的float属性赋值后,就是脱离文档流,进行左右浮动,紧贴着父元素(默认为body文本区域)的左右边框。浮动元素在文档流空出的位置,由后续的(非浮动)元素填充上去:块级元素直接填充上去,若跟浮动元素的范围发生重叠,浮动元素覆盖块级元素。浮动会覆盖块级元素。内联元素:有空隙就插入。环绕浮动元素,并不会被覆盖。

清除浮动的方式

通过浮动,我们能很方便地布局,但有带来很多的问题需要解决。文档中的普通流就会表现得和浮动框不存在一样,如果包含框太窄,无法容纳水平排列的三个浮动元素,那么其它浮动块向下移动,直到有足够的空间。如果浮动元素的高度不同,那么当它们向下移动时可能被其它浮动元素“卡住”。当浮动框高度超出包含框的时候,也就会出现包含框不会自动伸高来闭合浮动元素(“高度塌陷”现象)。元素含有浮动属性 – 破坏inline box – 破坏line box高度 – 没有高度 – 塌陷

正是因为浮动的这种特性,导致本属于普通流中的元素浮动之后,包含框内部由于不存在其他普通流元素了,也就表现出高度为0(高度塌陷:父元素只包含浮动元素,且父元素未设置高度和宽度的时候)。在实际布局中,往往这并不是我们所希望的,所以需要闭合浮动元素,使其包含框表现出正常的高度。

要想阻止行框围绕浮动框,需要对该框应用clear属性。clear属性的值可以是left、right、both 或 none,它表示框的哪些边不应该挨着浮动框。clear:left | right | both | none;但并不能解决“高度塌陷”的问题。

IE下清除浮动准则很简单,使元素haslayout就可以了。如宽度值,高度值,绝对定位,zoom,浮动本身都可以让元素haslayout。显然, 首选zoom:1;不会干扰任何样式。非IE浏览器常用的是overflow属性,overflow:hidden;或是overflow:scroll都可以,不过由于后者经常一不小心出现滚动条,所以前者用的更多些。由于现代浏览器都支持after伪类,所以常常也会用after写入一个clear属性的元素清除浮动。当然,最投机取巧的方法就是直接一个放到当作最后一个子标签放到父标签那儿。

  1. 添加额外标签
    通过在float元素的父元素结束前加一个高为0宽为0且有clear:both样式的元素。例如

    ,其他标签br等亦可。
    优点:通俗易懂,容易掌握;
    缺点:会添加多少无意义的空标签,有违结构与表现的分离,在后期维护中将是噩梦。

    1
    2
    3
    4
    5
    6
    <div class="wrap" id="float1">
    <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. 父元素设置overflow:hidden,zoom:1
    overflow:hidden属性会强制父级元素扩大到包含浮动元素,zoom:1只是触发ie6的hasLayout模式,不会对其他浏览器产生影响。
    .fix{overflow:hidden; zoom:1;}
    优点:代码简洁,涵盖所有浏览器;
    缺点:overflow:hidden;是个小炸蛋,要是里面的元素要是想来个margin负值定位或是负的绝对定位,岂不是直接被裁掉了,所以此方法是有不小的局限性的。

  3. 父元素也设置浮动
    浮动父级元素,父级元素的高度就会扩大,直到完全包含它里面的浮动元素。如果使用这种方法,一定要在该父元素的下个同辈元素添加clear:both,确保浮动元素落到父级元素的下方。
    优点:不存在结构和语义化问题,代码量极少;
    缺点:使得与父元素相邻的元素的布局会受到影响,不可能一直浮动到body,不推荐使用。

  4. 使用:after 伪元素

    1
    2
    .fix{zoom:1;}
    .fix:after{display:block; content:'clear'; clear:both; line-height:0; visibility:hidden;}

after,就是指标签的最后一个子元素的后面。于是呢,我们可以用CSS代码生成一个具有clear属性的元素, 优点:不存在结构和语义化问题,代码量极少;
缺点:使得与父元素相邻的元素的布局会受到影响,不可能一直浮动到body,不推荐使用

参考: