分享

CSS清除浮动专题

 昵称39360 2011-06-19

CSS清除浮动专题

W3C规范推荐在容器底部添加一个clear:both的元素

开篇:什么是CSS清除浮动,为什么要清除浮动?

»什么是CSS清除浮动?

网络上流行的说法是:在非IE浏览器(如Firefox)下,当容器的高度(height) 为auto,且容器的内容中有浮动(float为left或right)的元素,在这种情况下,容器的高度不能自动伸长以适应内容的高度,使得内容溢出到 容器外面而影响(甚至破坏)布局的现象。这个现象叫浮动溢出,为了防止这个现象的出现而进行的CSS处理,就叫CSS清除浮动。

»出现浮动溢出的条件是什么?

  • 首要条件:height:auto,或者说高度是自动伸展的。
  • 传统观念:只有Firefox和Opera才需要进行浮动清除。
  • 很抱歉,IE6和IE7都会。
下面这个浮动溢出的例子就是在IE6/IE7,Firefox和Opera下都会出现浮动溢出:
浮动溢出的例子
这是一个float:left的层,正常来说,它会向外溢出它接触到的父层。本层嵌套于 容器1
这是一个普通的“静态”层,没有任何与float相关的设定,叫 容器1
本层嵌套于容器2,设置了float:right。
这个层叫 容器2,与 容器1 区别不大,不同之处是上下margin都为60px。大家量一量,这里的上下margin是以哪个元素为参照的?

点击查看:浮动溢出的条件?

点击查看:清除浮动的最佳方法!

»为什么要CSS清除浮动和需要一个怎样的方法?

  • 实现容器高度随内容自动伸缩而不受其它内外元素影响。
  • 通过编写CSS简单实现,不用编写Javascript。
  • 寻找一个方法:为实现浮动清除,尽量不要对容器作太多的修改。
  • 这个方法尽量从外观样式中独立分离,不耦合于样式中,纯粹,不易受改变(健壮),可重用性强(这也是CSS好处之一)。

几个关键词[?]

方法一(W3C规范?):只要最底部有一个clear:both的元素?

  • 这里的 容器2 就是红边框的最后一个元素了,且clear为both了,只是在非IE下依然不能解决问题。
  • 如果该元素内部又出现一个浮动元素的话,就不行了,如 容器2 内的一个float:right的元素。
效果展示1:
这是一个float:left的层,正常来说,它会向外溢出它接触到的父层。本层嵌套于 容器1
这是一个普通的“静态”层,没有任何与float相关的设定,叫 容器1
本层嵌套于容器2,设置了float:right。
这个层叫 容器2,与 容器1 区别不大,不同之处是设置了clear:both,以及上下margin都为60px。大家量一量,这里的上下margin是以哪个元素为参照的?注:[?]
  • 关于margin-top:[?]
  • 我认为,W3C规范说的“在容器底部添加一个可识别的clear元素”,被人们断章取义地理解错了,才会出现效果展示1这样的误会。或者Easyclearing.html就是误会之源。
  • 正确的理解:所有需要进行浮动清除的容器的底部添加一个可识别的clear元素。[?]
  • 基于这个理解,请看方法二

方法二(可行):添加一个 clear:both空元素

  • 即在容器的最后添加一个<div style="clear:both;"></div>
  • 只要这个clear元素里面什么也不放,就不会出现上面的问题啦。
效果展示2:
这是一个float:left的层,正常来说,它会向外溢出它接触到的父层。本层嵌套于 容器1
这是一个普通的“静态”层,没有任何与float相关的设定,叫 容器1
这是个clear:both的空元素,为了看得出来,我还是了加点修饰。
本层嵌套于容器2,设置了float:right。
这个层叫 容器2,与 容器1 区别不大,不同之处是设置了clear:both,以及上下margin都为60px。大家量一量,这里的上下margin是以哪个元素为参照的?
这是个clear:both的空元素,为了看得出来,我还是了加点修饰。
  • 即在容器的最后添加一个<div style="clear:both;"></div>
  • 只要这个clear元素里面什么也不放,就不会出现上面的问题啦。
  • 不只是div,好些元素也可以用来做clear,看你怎么想了,这时在CSS中最好这样写(出自from some body I forgot):
    代码展示1:
    html body .clear,
        html body div.clear,
        html body span.clear,
        html body li.clear,
        html body dd.clear {
        background: none;
        border: 0;
        clear: both;
        display: block;
        float: none;
        font-size: 0;
        list-style: none;
        margin: 0;
        padding: 0;
        overflow: hidden;
        visibility: hidden;
        width: 0;
        height: 0;
        line-height: 0;
        font-size: 0;
        }

    这样写的好处是:加大clear标签的优先权不容易被覆盖;该0的是0,该是块元素的必须是块元素等强制设定,能增加稳定性,对付更多的复杂结构。

  • 缺点1:在每个容器底部添加空元素,会增加代码的数量
  • 缺点2(或许值得讨论):在IE6下出现容器高损坏现象(这情况似乎未见其他人发生过,难道一直都是我代码有错?)。
    图片展示1:

    brokenheight screenshoot

    IE6和IE7都会有此问题。[?]
    更详细的例子请点击这里:IE6/IE7的高属性破坏现象

    这个问题我称之为broken height in IE6(或者早就有人用其它名字命名过了),解决方法就是在容器中设置 height和width不得同时为"auto"或"inherit"之一等。

    »具体请看:避免高属性破坏(broken)的CSS属性设置(NEW)

    处理后也可以在IE6中通行了,请看效果展示3

    效果展示3:
    这是一个float:left的层,正常来说,它会向外溢出它接触到的父层。本层嵌套于 容器1
    这是一个普通的“静态”层,没有任何与float相关的设定,叫 容器1height:1%
    这是个clear:both的空元素,为了看得出来,我还是了加点修饰。
    本层嵌套于容器2,设置了float:right。
    这个层叫 容器2,与 容器1 区别不大,不同之处是设置了clear:both,以及上下margin都为60px。大家量一量,这里的上下margin是以哪个元素为参照的?
    这是个clear:both的空元素,为了看得出来,我还是了加点修饰。
总结:综上所述,在容器底部添加一个clear过的空元素可以很好的实现CSS浮动清除,只是在IE6中却要对容器进行一个很小的修改,只差一步就实现零耦合了。而且需要为了IE6进行两头设置,毕竟是不太方便,而方法三就干脆直接修改容器了。请继续看 方法三

方法三(可行):使用伪类 :after

用下面的 代码展示2 建立一个 clearfix 样式,并把它添加到容器的class中。

方法出处:Easyclearing.html

代码展示2:
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix {display: inline-block;}
/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */
效果展示4:
这是一个float:left的层,正常来说,它会向外溢出它接触到的父层。本层嵌套于 容器1
这是一个普通的“静态”层,没有任何与float相关的设定,叫 容器1class="clearfix"
本层嵌套于容器2,设置了float:right。
这个层叫 容器2,与 容器1 区别不大,不同之处是设置了clear:both,以及上下margin都为60px。大家量一量,这里的上下margin是以哪个元素为参照的?class="clearfix"
class="clearfix"
  • 正如W3C标准规范所述,如果想清除浮动,我们是不得不容器的最后或(本方法)或(方法二)地添加一个clear为 both 的元素。
  • 这个方法对容器的处理很巧妙,但使用的hack比较多。我不喜欢hack,在非逼于无奈的情况下是不会去hack的,所以我之前一直用 方法二,但现在我更喜欢灵活运用。

方法四(有争议):容器的overflow为auto或hidden?

效果展示5:
这是一个float:left的层,正常来说,它会向外溢出它接触到的父层。本层嵌套于 容器1
这是一个普通的“静态”层,没有任何与float相关的设定,叫 容器1overflow:auto;
本层嵌套于容器2,设置了float:right。
这个层叫 容器2,与 容器1 区别不大,不同之处是设置了clear:both,以及上下margin都为60px。大家量一量,这里的上下margin是以哪个元素为参照的?overflow:hidden;
overflow:auto;
  • 这是传说中的新方法,可在我的IE6中,却得到了 完全相反 的效果——浮动溢出!

    图片展示2:

    this make ie6 flow out!

  • 你在IE6下看到的 效果展示5 会像上图(图片展示2)那样出现“浮动溢出”吗?
  • 能,我相信,因为 容器1容器2 的宽度为auto时IE6是不起作用的,具体请看回:浮动溢出的条件
  • 除了这些条件,在我仅能得到的Firefox2、Firefox3b4/b5及IE7中就没有其它问题。详细演示
  • 不推荐使用此方法。 除了此方法在IE6下没效果外,还会导致另外一些问题,请看aoao的 慎用 overflow

方法五(太片面):overflow为auto/hidden/scroll,关键是width:100%?!

  • 该方法与 方法四 相似,也是为窗口设置overflow一个值(必须为auto/hidden/scroll当中的一个),只是说:关键在于,要把容器的宽度设为100%。
    效果展示6:
    这是一个float:left的层,正常来说,它会向外溢出它接触到的父层。本层嵌套于 容器1
    这是一个普通的“静态”层,没有任何与float相关的设定,叫 容器1overflow:auto; width:100%;
    本层嵌套于容器2,设置了float:right。
    这个层叫 容器2,与 容器1 区别不大,不同之处是设置了clear:both,以及上下margin都为60px。大家量一量,这里的上下margin是以哪个元素为参照的?overflow:hidden; width:100%;
    overflow:auto; width:100%;
  • 有人称这是世界上最简单的清除浮动方法,而我认为这方法太片面了,而且根本就不是“方法”。
  • 对width值的设定只是一个IE6下出现浮动溢出的条件之一。
  • width设为100%才行,那我的400px就不行了?而且100%后,padding怎么办,margin怎么办,border怎么办?思考太不全面了。

    图片展示3:

    layout

方法六(惊人发现?):float设置为left或right!

效果展示7:
这是一个float:left的层,正常来说,它会向外溢出它接触到的父层。本层嵌套于 容器1
这是一个普通的“静态”层,没有任何与float相关的设定,叫 容器1float:left; width:390px;
本层嵌套于容器2,设置了float:right。
这个层叫 容器2,与 容器1 区别不大,不同之处是设置了clear:both,以及上下margin都为60px。大家量一量,这里的上下margin是以哪个元素为参照的?float:left; width:390px;
float:left;
  • 还有比这更“惊人”的发现么?
  • 我们清除浮动的目的,是为了让容器能达到这样一个要求:即使在子层元素出现浮动的情况下,高度仍然能与子层同步扩展拉长,不会出现子层元素溢出到外部的现象。[?]
  • 正如开篇言:清除浮动,我们要轻手轻脚地进行,尽量不要对容器有太多的干扰,这也是清除浮动的原因之一。被处理的容器是 height是auto,这也是元素的默认值,只要这样才出现高度自动拉伸的需要;相反,如果对容器的高度进行了设定,或者用JavaScript对元素 高度进行控制,就不是我们要寻找的方法了。
  • 但是,假如我们找的不是这样一个“CSS清除浮动”方法,而是为了实现目的,那么我们就可以灵活运用列出的浮动溢出的条件了。

你的新发现?

  • 基于我的视野与经验,似乎找不到其它完全独立于上面的新方法了,其中有很多所谓的新发现其实只不是过“浮动溢出条件”中的一些影子而已,万变不离其宗。
  • 如果你有新发现,请与我分享。my email address
  • 再者,脱离了结构的CSS几乎不能存活,以我的理解是:凡事皆有一度,适可而止也。请看“最佳方法”。

清除浮动最佳方法

  • CSS清除浮动,就像天下间没有十全十美的人,也没有万能的机器一样——没有完美的解决清除方法,也没有一应万全的解决方案,要实现零耦合已经不可能了。
  • 所谓团结就是力量,如果我们合理地交替地使用一些可行方法,如 方法二方法三,再加上对浮动溢出的条件的运用,我们在页面制作中就不会成为单边撇子了。
  • jQuery的作者似乎也准备把浮动清除问题也考虑进jQuery。
  • 怎么灵活运用法呢?请看 讨论结果!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多