css之再谈浮动定位float(深入理解篇)
在现代开发中,float实际上已经很少使用,因为有更好用的flex布局。但float有他的历史地位,我学的第一个定位方式就是float。而且在面试中经常被提问,引出经典的BFC问题。实际上,float已经成为一个前端僵尸属性,用的不多,也不好用,但面试又被经常提及。
float的本质
float本质上就是做图文环绕的,这是他设计的目的,定位只是顺带的。也正是因为这一特性,在float身上有一些奇怪且不和逻辑的现象。这让用户用起来非常的困惑,对于初学者来说,这些困惑可以是致命的,不知道为什么,又搞不清楚,并且这对一个有着几年经验的前端来说,也是不容易搞清的。之所以这么说,是因为float有些现象是没有逻辑的,或者存在矛盾的地方。请看下面这个例子。
奇怪的空间占用问题(脱离文档流,但仍然会影响其他元素的布局。)
注意我标题的这句话:脱离文档流,但仍然会影响其他元素的布局。怎么影响其他元素布局?这个规则是没有明确提出的,但是,经过我的测试总结,可以用一个规律总结:左浮占空间,右浮不占空间。 你要问为什么?我只能说没有为什么,浏览器引擎内部就是这样设计的。
下面你可以带着这句话解释下面的现象,就都解释的通了。
情况1:
我们定义三个div。让div1和div2分别左右浮动。div3写在两者后面。
这时候你会看到一个奇怪的现象。div3的背景颜色消失了,这是最明显的。但更奇怪的是,div3的渲染位置是在div1的下面,注意,在y轴div2的高度是比div1要高的,div3渲染在div1的高度位置,而不是渲染在div2的高度位置。
这是不合逻辑的。我们知道,浮动元素是脱离文档流的。既然脱离文档流,那么就不会占用空间。按照正常的逻辑,div3应该覆盖在div1上面。 正如标题所说,这是因为浮动虽然脱离文档流,但仍然会影响其他元素的布局。
这是最蛋疼的,正是因为这样,才会出现那么多奇怪的现象。
好消息是,只要你记住浮动虽然脱离文档流,但仍然会影响其他元素的布局。左浮占空间,右浮不占空间。(规律) 你就能解释这一切。
对于情况1的解释:
左浮占用空间,所有换行。 注意这是浏览器引擎规律。如果你要以有没有空间容纳来解释的话,情况2就会出现矛盾的地方。你只能说这是浏览器引擎的内部处理规则就是这样。
至于为什么div3渲染的高度位置是在div1的底部的高度位置,而不是div2底部的高度位置。这实际上你只能说现象就是这样。这东西实际上是内部渲染机制决定的,不需要强行解释为什么,你只需要知道他就是这样就行了。因为毕竟div3的背景颜色都丢失了,你还和我说这些?但是,如果你用左浮占空间,右浮不占空间。这个规律来说,就可以解释的通,因为左浮占空间,右浮不占空间,所以div3出现在div1底部的高度,而不是div2底部的高度。
情况2:
我们做一下改动,把div1注释。效果如下,div3占据了div1原版的位置。这似乎非常的合理,因为div2脱离文档流,不占用空间。好像又正常了,符合脱离文档流不占用空间的直观感受。但别高兴的太早。
对于情况2的解释:
还是记住浮动虽然脱离文档流,但仍然会影响其他元素的布局。左浮占空间,右浮不占空间。(规律)
现在div3跑到左边占据了原来div1的位置。是符合左浮占空间,右浮不占空间这个规律的。因为右浮不占空间,所以第一行是完全空白的,div3自然就可以渲染了。前面说过,如果要按有没有空间来解释的话,这里就会出现矛盾,div2虽然浮动,但是可能是占用空间的(事实上是不占用空间的)。那么div3就应该换行。但实际上div2右浮是不占用空间的。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Title</title><style>.box1 {width: 200px;height: 200px;background-color: lightblue;float: left;} .box2 {width: 300px;height: 300px;background-color: lightgreen;float: right;}.box3 {width: 200px;height: 200px;background-color: lightsalmon;/* clear: right; */}</style></head><body><!-- <div class="box1">1</div> --><div class="box2">2</div><div class="box3">3</div></body>
</html>
情况3:
我们把代码再改一改,这次把div2注释。和最开始的情况是非常相似的,只是div2不显示了。
这种情况实际上和情况1是差不多的。用左浮占空间,右浮不占空间。非常好解释。div1左浮占空间,所以div3换行,div2右浮不占空间,所以有没有都不影响div3的布局(和情况1结合对比。)。
颜色消失问题:
颜色消失不是因为被遮挡。只能说是浏览器渲染异常。或者说,这是一个bug或者渲染error。其实出现这种情况页面已经不能正常显示了,只是程序没有奔溃。你完全可以把它当成是渲染错误的体现。相当于报渲染错误了。
这就是所谓的高度坍塌问题。
总结:
解释这些奇怪的现象只需要记住下面这句话:
浮动虽然脱离文档流,但仍然会影响其他元素的布局。左浮占空间,右浮不占空间。(规律)
高度坍塌问题和clear属性
clear的属性的作用是设置一个元素是否允许旁边有浮动属性。这个属性是和float配套出现的。因为float主要是做图片环绕的,但如果你想让标题,分割线等不围绕图片,就可以使用clear属性。同时clear属性可以用于解决高度坍塌问题。
给div3设置clear:both属性后,div3的背景颜色就可以正常显示了。所谓的正常可以理解为现在div3就是一个正常的块元素,没有任何的东西影响他的布局。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Title</title><style>.box1 {width: 200px;height: 200px;background-color: lightblue;float: left;}.box2 {width: 300px;height: 300px;background-color: lightgreen;float: right;}.box3 {width: 200px;height: 200px;background-color: lightsalmon;clear: both;}</style></head><body><div class="box1">1</div><div class="box2">2</div><div class="box3">3</div></body>
</html>
如果我们设置了clear: right;那么效果和clear: both;是一模一样的。对于div3来说,设置了clear: right;右浮就没有效果,那么div2就要占据空间大小,形成上图的效果是合理的。
.box3 {width: 200px;height: 200px;background-color: lightsalmon;clear: right;}
如果我们设置了clear: left;那么效果如下图所示:
我们可以这样理解:现在左浮没有效果了,所以div1占据大小,而div2因为右浮,大小被忽略,所以div3的高度位置是在div1下面。
.box3 {width: 200px;height: 200px;background-color: lightsalmon;clear: right;}
总结,如果你把这个例子的几种情况都理解了,那么float 90%的内容都理解了,而所谓的BFC也只是顺手的事。会单独开一篇讲BFC问题。