CSS float浮动的深刻研究、详解及拓展(二)

接上回… php

5、浮动的非本职工做

浮动的本职工做是让匿名inline boxes性质的文字环绕图片显示,而其余全部用浮动实现的效果都不是浮动应该作的事情,我称之为“非本职工做”。 css

或许咱们并无过多的深思,把一些实际上不是浮动该干的事情看成“这必须用浮动来实现”。举个常见的例子,列表显示,见下面的图,截自淘宝新版首页:
淘宝热卖单品截图 >> 张鑫旭-鑫空间-鑫生活
我不看代码就知道是用浮动实现的,我用firebug一看,果真是,不只浮动,并且定宽。ps:要是在几个月之前,我会以为这实在有待改进,不过如今个人心态宽了,布局思想不一样而已,没有孰对孰错之分。
代码截图 web

我能够确信,浮动这个属性诞生的那天压根没有想到本身会要作这样的事情,原本它觉得本身就让文字环绕显示就OK了,功德圆满了,结果,在web2.0的时代,其却在页面布局中被滥用。可能有人会反驳,你何处此言,有何证据? 浏览器

咱们只要静下心来好好想一想浮动的本质,实现的原理,就能够知道为何浮动本不该该用来对页面进行布局。还记得上一部分所说的浮动的本质吗?即“包裹与破坏”。咱们能够用这个(“包裹与破坏”)解释为何浮动可让li这类block水平的元素水平排列。 wordpress

单个无浮动的li元素 布局

看下面的HTML代码:
<ul style="width:440px;">
    <li style="border:4px solid #ff6633; background:#ffffc0;"><img src="../image/border.png" /></li>
</ul>

结果以下图(截自Firefox浏览器,无其余样式干扰,下同):
来自张鑫旭-鑫空间-鑫生活 单个无浮动li元素 性能

这里的li元素为何会有高度?若是您认真读过前半部份内容关于line boxes模型与高度的关系的内容,应该知道,因为图片没有应用float属性,其自己有一个正常的inline box,这个inline box高度等于图片的height,在这行元素中,图片这个inline box的高度最高,因而传递给了line box,line box是个真正意义上的高度,直接做用于containing box(就是这里的li元素,使li元素有一个高度)。理解了这个您就会明白为何要是这里的图片添加了float属性,li高度会塌陷了:浮动破坏了inline box。这个后面会详细讲解。 测试

这里的li没有添加float属性,能够见到li宽度100%自适应于父ul标签。一切显得那么的和谐! 网站

单个左浮动的li元素 spa

看下面的HTML代码:
<ul style="width:440px;">
    <li style="border:4px solid #ff6633; background:#ffffc0; float:left;"><img src="../image/border.png" /></li>
</ul>

结果以下图:
来自张鑫旭-鑫空间-鑫生活 单个浮动li元素

相比上面而言,这里多了个float:left;,浮动的“包裹性”一目了然:水平方向上,li宽度紧贴内部元素。我在前文曾说过这么句结论性的话:“撇开浮动的‘破坏性’,浮动就是个带有方位的display:inline-block属性”。这不难理解,您能够讲这里的float:left;改为display:inline-block;最后实现的效果基本上就是同样的。display:inline-block将对象呈递为内联对象,可是对象的内容做为块对象呈递。所谓对象呈递为内敛对象就是元素呈递为inline box,因此浮动“包裹性”所产生的结果就是使得元素转为了line box模型中的inline box元素。

浮动的“包裹性”让元素变成相似于inline box的元素,而浮动的“破坏性”正是破坏inline box元素的,这其中岂不有矛盾。其实非也,对于block水平的这类块状元素须要先让其变成相似效果的内联元素,而后再破坏之,实乃先诱拐再奸杀的生动实例啊!

又是我反复提到的,浮动破坏了inline box,也就是破坏了高度,因此这里含有浮动属性的li元素其实是没有高度的。因此呢,要是后面还有一样的li标签的话,就会水平对齐排列的。以下:

多个左浮动的li元素

看下面的HTML代码:
<ul style="width:440px;">
    <li style="border:4px solid #ff6633; background:#ffffc0; float:left;"><img src="../image/border.png" /></li>
    <li style="border:4px solid #ff6633; background:#ffffc0; float:left;"><img src="../image/border.png" /></li>
</ul>

结果以下图:
来自张鑫旭-鑫空间-鑫生活 多个浮动li元素

左浮动的li元素和无浮动的li元素

看下面的HTML代码:
<ul style="width:440px;">
    <li style="border:4px solid #ff6633; background:#ffffc0; float:left;"><img src="../image/border.png" /></li>
    <li style="border:4px solid #ff6633; background:#ffffc0;"><img src="../image/border.png" /></li>
</ul>

结果以下图:
来自张鑫旭-鑫空间-鑫生活 左浮动的li元素和无浮动的li元素

后面一个li无float属性,直接无视前面的float li元素,宽度100%显示,并且与float属性的li同一水平线排列,为什么?由于浮动破坏了li的实际高度(缘由我讲得太屡次了),只是图片是个实体,没法与一样实体的同一文档流的图片重合,因此图片靠在一块儿。

6、证据

1. 首要证据

前文是着重分析了浮动的“本职工做”:文字环绕显示;本文着重分析了浮动的“非本职工做”:列表布局;二者都是用的一样的原理解释的,那么有什么证据能够证实“页面布局”不是浮动的“本职工做”呢。答案关键字就是:高度塌陷

我在多个地方浓墨重彩的讲浮动与高度的关系,浮动使高度塌陷的缘由,本身都以为唠叨的太多了,这里再也不讲。直接讲些实际的东西。

您是否发现,浮动布局会让父标签高度缺失,可是实现文字环绕图片效果的时候父标签无需清除浮动。仍是上面的例子,咱们看看多li元素浮动时ul标签高度在哪里,咱们能够给ul加个边框属性作测试,测试代码以下:

<ul style="width:440px; border-top:4px solid #a0b3d6; border-bottom:4px solid #34538b;">
    <li style="border:4px solid #ff6633; background:#ffffc0; float:left;"><img src="../image/border.png" /></li>
    <li style="border:4px solid #ff6633; background:#ffffc0; float:left;"><img src="../image/border.png" /></li>
</ul>

结果以下图:
来自张鑫旭-鑫空间-鑫生活 浮动元素父标签高度

上图显示ul高度为0,这是必然的,正常的,应该的。您要是在IE下看到ul有高度,认为这是Firefox等浏览器有问题就错了,您把ul的width属性去掉,看看,会发现IE下ul高度也为0, 这是IE的layout做祟。至于为何ul高度为0,我前面不少地方都已经讲了,再也不说了。可是,从中咱们能够看到,浮动本不是用来列表布局的,而是用来使元素环绕显示的,由于元素环绕(例如文字),其自身是含有inline boxes高度的,这是inline水平的元素造成高度的基础,因此,虽然浮动元素没有高度,可是其周围环绕的元素是有高度的,只要环绕元素比浮动元素高度高,父标签无高度的问题天然也就没有了,可是纯粹一堆浮动元素会有高度吗?没有。因此浮动元素塌陷的问题根本就不是浏览器的bug,而是咱们没有正确地深刻地了解浮动,是咱们本身使用不当,由于浮动本不该该用在这里的。

2. 其余证据

为何说浮动的本职工做不是页面布局而应该是是元素环绕呢。还有其余些证据。

历史

CSS刚诞生的时候,那时候的网页仍是表格布局的时代,能显示几张图片就不错了,复杂的列表显示,布局啊这些概念仍是很淡薄的,浮动出现的意义就是让文字可以环绕图片显示而已,就如word般。

现象

Google是目前互联网领域的老大,技术很牛叉,毋庸置疑,可是,当我发现它全部的页面几乎都是表格布局的时候,很诧异;还有twitter,也是表格布局的;
twitter表格布局 >> 张鑫旭-鑫空间-鑫生活
为何这些顶尖的web网站使用表格布局,而不跟随潮流呢,起初我是百思不得其解。如今,我是明白了,这么作是有他的道理的,难道要用一堆浮动的元素去布局吗?这不是浮动该干的事情。并且,浮动是个很很差惹的魔鬼。

7、浮动是个魔鬼、混球

浮动的存在就是个破坏。浮动效果的实现就是先破坏自身(挥刀自宫),而后影响别人。页面中只要出现一个浮动,势必有其余元素受其影响。这是开发和维护中的一个定时炸蛋(敏感词)。咱们想一想浮动的意义,只是让文字环绕图片显示而已,因此其必须破坏自身模型和高度。可是,不知道幸运仍是不幸,浮动的这种置之死地然后生的特性竟然可让元素布局,加上其表面意思很好理解,兼容性还不错,使用方便,因而在舍弃了table布局的这个web时代里,浮动成为当前页面布局的主流。想一想,真是一件可怕的事情。

有些人可能没有意识到浮动实际上是个很糟糕的东西,是CSS中的一个魔鬼。为何,或许由于用浮动布局页面发现还行,即便偶尔出现些小bug,打打补丁也能够解决。或许是由于没有体会到非浮动元素和浮动元素在开发和维护上所消耗的成本精力的差异。有些人可能知道浮动这个属性能不用就不用,可是因为找不到更好的替代方法,因此仍是有不少地方使用了浮动布局,例如选项卡,列表显示等。

理论上而言,除了浮动的环绕效果以外,咱们使用浮动作的其余工做均可以使用别的CSS属性实现,并且大部分状况是比浮动的效果好:首先没有了清楚浮动一说,二是有关浮动的一堆bug也不会出现,三是元素间独立了,不会像浮动同样改变一个会影响其余。可是,考虑到大多数人对CSS掌握的程度,以及浏览器的一些兼容性问题等,不少时候,咱们不得不使用看上去使用方面但潜在问题较大的浮动属性。因此,有关浮动的一些特性的研究仍是颇有必要的,这就是下面的重点。

8、解决高度塌陷的问题 – 清除浮动

CSS中有个讨论较多的话题就是如何清除浮动,清除浮动其实就一个目的,就是解决高度塌陷的问题。为何会高度塌陷?何时会高度塌陷?塌陷缘由是:元素含有浮动属性 – 破坏inline box – 破坏line box高度 – 没有高度 – 塌陷。何时会塌陷:当标签里面的元素只要样子没有实际高度时会塌陷。因此呢,并非只要有浮动元素就会坍塌,就要清除的,CSS水平高低衡量的标准之一就是改用什么样式就用什么样式,很少用也很多用。

下面就来说讲如何清除浮动,zxx:写到这儿,一会儿轻松了。
IE下清除浮动准则很简单,使元素haslayout就能够了。如宽度值,高度值,绝对定位,zoom,浮动自己均可以让元素haslayout。显然,首选zoom:1;不会干扰任何样式。非IE浏览器经常使用的是overflow属性,overflow:hidden;或是overflow:scroll均可以,不过因为后者常常一不当心出现滚动条,因此前者用的更多些。因为现代浏览器都支持after伪类,因此经常也会用after写入一个clear属性的元素清除浮动。固然,最投机取巧的方法就是直接一个<div style="clear:both;"></div>放到看成最后一个子标签放到父标签那儿。下面小结这几个方法。

1. 投机取巧法

就是直接一个<div style="clear:both;"></div>放到看成最后一个子标签放到父标签那儿,此方法屡试不爽,兼容性强,使用方便,是初学时使用的上佳之选。可是我历来不用,由于我看到的是个巨大的浪费,浪费了一个标签,并且只能使用一次,我我的是没法容忍的,因此这个方法不推荐。并且有时候一不留神中间多了个空格会产生一段空白高度的。

2. overflow + zoom方法

.fix{overflow:hidden; zoom:1;}

此方法优势在于代码简洁,涵盖全部浏览器,可谓不错的选择啊。不过也是有问题的,就是这个overflow:hidden;是个小炸蛋,要是里面的元素要是想来个margin负值定位或是负的绝对定位,岂不是直接被裁掉了,因此此方法是有不小的局限性的。我通常不用这个方法,只是有时候顺便去除浮动时用用。

3. after + zoom方法

先来简单讲讲after,所谓after,就是指标签的最后一个子元素的后面。因而呢,咱们能够用CSS代码生成一个具备clear属性的元素,其中的关键样式就是content了。或许您从网上看到的content里面的内容是”.”一个点,我了不少次,貌似随便写什么东西都没有问题,好比content:'clear both';没问题,或是content:'张鑫旭'也是ok的。因而有:
.fix{zoom:1;}
.fix:after{display:block; content:'clear'; clear:both; line-height:0; visibility:hidden;}

这里的line-height:0写成height:0也是能够的。此方法能够说是综合起来最好的方法了,我都是用这个样式清除浮动的,不会影响任何其余样式,通用性强,覆盖面广,我很推荐哦。

9、float与JavaScript

JavaScript能够改变CSS的属性,其余些属性还好,可是这个float值得一说,为什么呢,由于float貌似是JavaScript中的一个关键字,不能使用obj.style.float="left";这样的句子。得使用其余写法。

IE浏览器:
obj.style.styleFloat = "left";

其余浏览器:

obj.style.cssFloat = "left";

10、最后的总结

其实本来是想经过深刻分析浮动的前世此生,本质意义来揭示其丑陋的真面目的,多是在文字表达上还欠火候,总以为表达的有些凌乱,估计很轻松就知道我在说什么的人较少,原本是篇颇有技术含量的文章,可是在表现上作的不够好,多是内容太多,本身想要表达的内容太多,因而反而有些混乱。因此,最后其实不少东西没有继续详细展开讲解,例如清除浮动的本质是什么?浮动产生一系列bug的根本缘由是什么?浮动布局更好的替代方案是什么?由于内容已经够多够乱的了,因此我决定这些内容留到之后,思路清晰的时候再表述出来。

本文能够说是有别于目前绝大多数关于浮动的文章,我没有讲浮动的使用实例啊之类的东西,也没有去分析浮动的一些特性,仅仅从最根本的地方分析浮动,我想这个比单纯的讲解几个浮动的应用做用更深远。并且还有一点,本文其实某种程度上是批判浮动的,但愿开发者尽量的少使用浮动,少使用浮动去作些其实并非浮动应该作的事情。因此要是花功夫讲浮动的应用的话就是搬石头砸本身的脚。

本文不少理论的东西,可能是本身的我的看法,因此实际上有些认识多是不许确的,欢迎有不一样观点的同行们反驳,也欢迎交流(经过评论或是去这里进行提问交流)。

转载自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
(本篇完)

相关文章
相关标签/搜索