html css 深入理解float
首先,我们来看一段权威的关于float的解释:
“浮动会让元素脱离文档流,不再影响不浮动的元素。实际上,并不完全如此。如果浮动的元素后面有一个文档流中的元素,那么这个元素的框会表现得像浮动元素根本不存在一样。但是,框的文本内容、背景色、边框会受到浮动元素的影响,会移动以留出空间。用技术术语来说,浮动元素旁边的行框被缩短,从而给浮动元素留出空间,因此行框围绕浮动框。”
框可以理解成:块状元素;行框可以理解成行内块元素和行内元素。
参考链接:https://www.zhihu.com/question/45507310?sort=created
(一)我们定义了三个div,分别命名为a,b,c;代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 .a{ 8 width: 100px; 9 height: 100px; 10 border: 1px solid black; 11 background-color: #a4e2c6; 12 } 13 .b{ 14 width: 100px; 15 height: 100px; 16 border: 1px solid black; 17 color: white; 18 background-color: #ffc773; 19 } 20 .c{ 21 width: 100px; 22 height: 100px; 23 border: 1px solid black; 24 color: red; 25 background-color: blue; 26 } 27 </style> 28 </head> 29 <body> 30 <div class="a">Number One</div> 31 <div class="b">Number Two</div> 32 <div class="c">number Three</div> 33 </body> 34 </html>
显示效果:
(二)下面我们来改一下代码,我们将div(a)增加float:left;代码如下如示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>float练习</title> <style type="text/css"> .a{ float: left; width: 100px; height: 100px; border: 1px solid black; background-color: #a4e2c6; } .b{ width: 100px; height: 100px; border: 1px solid black; color: white; background-color: #ffc773; } .c{ width: 100px; height: 100px; border: 1px solid black; color: red; background-color: blue; } </style> </head> <body> <div class="a">Number One</div> <div class="b">Number Two</div> <div class="c">number Three</div> </body> </html>
从上面的显示的效果来看的话,我们会发现一个很奇怪的现象,就是为什么文字Number Two和number Three会出现重叠的现象呢?
我们来分析一下;为什么div(b)不见了?它跑哪里去了?
当我们设置div(a) float:left以后,div(a)就脱离了文档流了,脱离了文档流以后就不占据文档原来的空间了(毕竟已经飘起来了)。
此时,div(b)就会向上运动,去占领div(a)原来的领地。因为div(a)已经飘起来了,漂浮在div(b)的上面。所以我们就发现div(b)不见了,只能看到
div(a)的身影,其实div(b)被人家div(a)压在下面了呢。(羞羞羞```)
毕竟div(a)和div(b),同宽同高,从视觉上看,两个div才能合二为一呢。
解释完了div(b)为什么不见,那接下来,就应该解释为什么文字Number Two和number Three会出现重叠的现象呢?
由权威的解释我们可以知道,框的文本内容会受到浮动元素的影响,会移动以留出空间。
这足以说明float脱离文档流,其实并不是很彻底的。框的文本内容会受到浮动元素的影响。
换句话说,div(b)奋不顾身的去占领div(a)的老巢,但是div(b)的文本可是有一颗慈善之心的,打死都不肯进入div(a)的领域,一心甘愿在div(a)的周边呆着,形成一个文字环绕的现象。
这就要回到float设计的出发点了,当时设计者设计float的时候,就是把它用作文字环绕的。
float设计最初的主要效果和功能就是要让文本环绕图片,如果给块状元素设定float,就是文本环绕块状元素呀。
因为div(a)和div(b)同高同宽,所以div(b)的文本又不进入div(a)的领域,就只能停留在div(a)的下方位置了。
而div(c)是因为div(b)的上移而上移,上移的过程当中,就恰巧遇到了在div(a)外面的Number Two文本了,就造成了div(b)和div(c)文本的重叠的现象。
(三)下面我们来改一下代码,我们将div(a)增加float:left的同时,将div(b)的宽度加大,来看一下代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 .a{ 8 float: left; 9 width: 100px; 10 height: 100px; 11 border: 1px solid black; 12 background-color: #a4e2c6; 13 } 14 .b{ 15 width: 300px; 16 height: 100px; 17 border: 1px solid black; 18 color: white; 19 background-color: #ffc773; 20 } 21 .c{ 22 width: 100px; 23 height: 100px; 24 border: 1px solid black; 25 color: red; 26 background-color: blue; 27 } 28 </style> 29 </head> 30 <body> 31 <div class="a">Number One</div> 32 <div class="b">Number Two</div> 33 <div class="c">number Three</div> 34 </body> 35 </html>
显示效果:
由上面的效果图,我们可以很清楚的看到,因为div(b)的宽度空间足够,此时div(b)的文本不再和div(c)的文本发生重叠。
依旧秉承着与div(a)秋毫与犯,相敬如宾的态度,所以依旧守护在div(a)的区域外围,环绕着它,形成了这么一个文字与块状元素div(a)环绕的现象。
说了这么多,那我们应该知道了float的本意是什么了吧?让文字像流水一样环绕浮动元素;
(补充:2017/9/29)框的文本内容、背景色、边框会受到浮动元素的影响,会移动以留出空间。
起初的时候,还以为只是框(block块级元素)的文本内容会受到浮动的元素的影响,会移动以留出空间,后面发现错了。原来框的背景色,边框也会受到浮动元素的影响。
下面来看一段代码吧:
①当我们不设置div2的背景色,边框,只设置文本内容的情况:代码如下所示:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>清除浮动</title> 6 <style type="text/css"> 7 .div1{ 8 width: 200px; 9 border: 4px solid blue; 10 background-color: red; 11 float: left; 12 } 13 .div2{ 14 width: 208px; 15 } 16 </style> 17 </head> 18 <body> 19 <div class="div1">我是浮动元素div1</div> 20 <div class="div2">我是浮动元素div2</div> 21 </body> 22 </html>
显示效果:
②当我们设置div2的背景色,边框,文本内容的情况:代码如下所示:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>清除浮动</title> 6 <style type="text/css"> 7 .div1{ 8 width: 200px; 9 border: 4px solid blue; 10 background-color: red; 11 float: left; 12 } 13 .div2{ 14 width: 200px; 15 border: 4px solid black; 16 background-color: yellow; 17 } 18 </style> 19 </head> 20 <body> 21 <div class="div1">我是浮动元素div1</div> 22 <div class="div2">我是浮动元素div2</div> 23 </body> 24 </html>
显示效果:
由①②我们可以得知,当div1设置了浮动的时候,div2块会直接忽视它,占据div1的位置,但是块级里面的背景色,边框,文本都会围绕着div1,并不会占据它的空间。
参考链接:http://www.jianshu.com/p/07eb19957991
我们来了解一下float的包裹性和高度欺骗的特性。
特性一 包裹性
例1 首先,我们来看一段float包裹性特点的代码,如下所示:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 img{ 8 width: 200px; 9 height: 200px; 10 } 11 .container{ 12 width:800px; 13 } 14 .pic_ra{ 15 border: 4px solid blue; 16 } 17 .pic_tu{ 18 float: left; 19 border: 4px solid yellow; 20 } 21 </style> 22 </head> 23 <body> 24 <div class="container"> 25 <div class="pic_ra"> 26 <img src="image/rabbit.jpg" alt=""> 27 </div> 28 <div class="pic_tu"> 29 <img src="image/tuttle.jpg" alt=""> 30 </div> 31 </div> 32 </body> 33 </html>
显示效果:
由上图,我们可以很清楚的看到,当在div(pic_tu)上设置了float:left以后,它产生了包裹性。
由此,我们可以得出,当在div(block块元素)上设置浮动以后,它就会像inline内联元素一样,产生包裹性,宽度随内容自适应该。
注意:当block元素不指它width的时候,其默认宽度是100%。当block元素设置float以后,产生包裹性,所以浮动元素宽度就需要手动的指定。
下面我们在加一个div(pic_du),代码如下所示:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 img{ 8 width: 200px; 9 height: 200px; 10 } 11 .container{ 12 width:800px; 13 } 14 .pic_ra{ 15 border: 4px solid blue; 16 } 17 .pic_tu{ 18 float: left; 19 border: 4px solid yellow; 20 } 21 .pic_du{ 22 border: 4px solid green; 23 } 24 </style> 25 </head> 26 <body> 27 <div class="container"> 28 <div class="pic_ra"> 29 <img src="image/rabbit.jpg" alt=""> 30 </div> 31 <div class="pic_tu"> 32 <img src="image/tuttle.jpg" alt=""> 33 </div> 34 <div class="pic_du"> 35 <img src="image/duck.jpg" alt=""> 36 </div> 37 </div> 38 </body> 39 </html>
显示效果:
上图显示的效果,是因为div(pic_tu)设置了float:内浮动,脱离了文档流,div(pic_du)会主动忽视div(pic_tu),去占据它的空间。而img作为inline(内联元素),浮动元素旁边的行框被缩短,从而给浮动元素留出空间,因此行框围绕浮动框。从而出现图片围绕在浮动元素div(pic_tu)的周围,形成了并列显示的感觉了。
特性二 高度欺骗
例2 我们再来看一段float高度欺骗的代码,如下所示:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 img{ 8 width: 200px; 9 height: 200px; 10 } 11 .container{ 12 width:800px; 13 } 14 .pic_ra{ 15 border: 4px solid blue; 16 } 17 .pic_tu{ 18 border: 4px solid yellow; 19 } 20 .tu_img{ 21 border: 4px solid black; 22 float: left; 23 } 24 </style> 25 </head> 26 <body> 27 <div class="container"> 28 <div class="pic_ra"> 29 <img src="image/rabbit.jpg" alt=""> 30 </div> 31 <div class="pic_tu"> 32 <img class="tu_img" src="image/tuttle.jpg" alt=""> 33 </div> 34 </div> 35 </body> 36 </html>
显示效果:
上图的效果,我们先来分析一下,为什么div(pic_tu)变成了一条800px×8px(width×height)的黄色的直线了呢?
第一步,我们先解释800px×8px这个是怎么来的?
我们之前有提到过,当block元素(div(pic_tu)),它不指定宽度的时候,其默认的宽度为100%。在这里,很显然div(pic_tu)元素是其父div(container)的100%,即800px。因为(div(pic_tu))的边框是4px,上下边框加在一起,就变成了8px,也就是这里看到的height:8px。
第二步,我们来解释为什么就变成了一条直线呢?
这里与例1不同的是,我们把float的设置从div(pic_tu)转移到了img(tu_img),img(tu_img)作为div(pic_tu)的内容,已经飘浮起来了,因为脱离了文档流,不占据原来的空间,这样就造成了欺骗性。
为什么说具有了欺骗性了呢?因为img(tu_img)被float设置了障眼法,作为div(pic_tu)的内容的它,现在的line-height高度坍塌为0了。这样的话,外层的div(pic_tu)在计算高度的时候,认为img(tu_img)的高度为0,换句话说,就相当于div(pic_tu)的内容(content)的高度为0,所以就变成了一条黄色(div(pic_tu) border边框颜色)的直线了。
但是我们仔细看一下img(tu_img)设置的黑色边框的正常高度还是存在的,在它身上设置的float毕竟只是障眼法,其实并不是真的让img(tu_img)的高度坍塌为0了。
下面我们为改变一下代码,在div(pic_tu)里面加入一些文字,来看一上效果。代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 img{ 8 width: 200px; 9 height: 200px; 10 } 11 .container{ 12 width:800px; 13 } 14 .pic_ra{ 15 border: 4px solid blue; 16 } 17 .pic_tu{ 18 border: 4px solid yellow; 19 } 20 .tu_img{ 21 border: 4px solid black; 22 float: left; 23 } 24 </style> 25 </head> 26 <body> 27 <div class="container"> 28 <div class="pic_ra"> 29 <img src="image/rabbit.jpg" alt=""> 30 </div> 31 <div class="pic_tu"> 32 <img class="tu_img" src="image/tuttle.jpg" alt=""> 33 我是一个浮动的元素。龟鳖目俗称龟,其所有成员,是现存最古老的爬行动物。特征为身上长有非常坚固的甲壳,受袭击时龟可以把头、尾及四肢缩回龟壳内。大多数龟均为肉食性。龟是通常可以在陆上及水中生活,亦有长时间在海中生活的海龟。龟亦是长寿的动物,自然环境中有超过百年寿命的。龟鳖目现存2亚目约220种。遍布各大洋。 34 </div> 35 </div> 36 </body> 37 </html>
显示效果:
我们来思考一下?为什么div(pic_tu)会被撑开呢?
我们知道,外层div(pic_tu)在没有手动设置height高度的前提下,其高度是由它的内部的content(内容)最大的高度来决定的。
由于img(tu_img)设置了float,具有了高度坍塌的欺骗性,让div(pic_tu)误以为img(tu_img)的line-height高度为0。因此div(pic_tu)的高度就是文字的匿名inline-box的inline-height。
接下来,我们来模仿一个类似新浪微博好友列表的例子:
先看一段代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 ul{ 8 margin: 0px; 9 padding: 0px; 10 width: 245px; 11 background-color: yellow; 12 border: 1px solid black; 13 overflow: hidden; 14 } 15 img{ 16 width: 100px; 17 height: 100px; 18 border: 1px solid black; 19 } 20 li{ 21 float: left; 22 list-style: none; 23 width: 100px; 24 text-align: center; 25 font-family: SimHei; 26 margin: 0px 10px; 27 font-size:14px; 28 line-height: 20px; 29 } 30 </style> 31 </head> 32 <body> 33 <ul> 34 <li> 35 <img src="image/duck.jpg" alt=""> 36 <span>鸭子</span> 37 </li> 38 <li> 39 <img src="image/tuttle.jpg" alt=""> 40 <span>乌龟</span> 41 </li> 42 <li> 43 <img src="image/rabbit.jpg" alt=""> 44 <span>兔子</span> 45 </li> 46 <li> 47 <img src="image/duck.jpg" alt=""> 48 <span>鸭子</span> 49 </li> 50 </ul> 51 </body> 52 </html>
显示效果:
看上去,看正常对不对,和谐统一得不要不要的。但是,如果,这是一只来自俄罗斯的鸭子,那情况可就不一样了呢?
接来下,我们再看一段代码?代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 ul{ 8 margin: 0px; 9 padding: 0px; 10 width: 245px; 11 background-color: yellow; 12 border: 1px solid black; 13 overflow: hidden; 14 } 15 img{ 16 width: 100px; 17 height: 100px; 18 border: 1px solid black; 19 } 20 li{ 21 float: left; 22 list-style: none; 23 width: 100px; 24 text-align: center; 25 font-family: SimHei; 26 margin: 0px 10px; 27 font-size:14px; 28 line-height: 20px; 29 } 30 </style> 31 </head> 32 <body> 33 <ul> 34 <li> 35 <img src="image/duck.jpg" alt=""> 36 <span>我是一只来自俄罗斯的可达鸭子</span> 37 </li> 38 <li> 39 <img src="image/tuttle.jpg" alt=""> 40 <span>乌龟</span> 41 </li> 42 <li> 43 <img src="image/rabbit.jpg" alt=""> 44 <span>兔子</span> 45 </li> 46 <li> 47 <img src="image/duck.jpg" alt=""> 48 <span>鸭子</span> 49 </li> 50 </ul> 51 </body> 52 </html>
显示效果:
从显示的效果图来看,因为左上的图片的文字描述信息太长了,导致左下的图片都发生明显的错位了,影响了美观了。
下面,我们只需要将float:left;改成display:inline-block;
代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 ul{ 8 margin: 0px; 9 padding: 0px; 10 width: 245px; 11 background-color: yellow; 12 border: 1px solid black; 13 } 14 img{ 15 width: 100px; 16 height: 100px; 17 border: 1px solid black; 18 } 19 li{ 20 display: inline-block; 21 list-style: none; 22 width: 100px; 23 text-align: center; 24 font-family: SimHei; 25 margin: 0px 10px; 26 font-size:14px; 27 line-height: 20px; 28 } 29 </style> 30 </head> 31 <body> 32 <ul> 33 <li> 34 <img src="image/duck.jpg" alt=""> 35 <span>我是一只来自俄罗斯的可达鸭子</span> 36 </li> 37 <li> 38 <img src="image/tuttle.jpg" alt=""> 39 <span>乌龟</span> 40 </li> 41 <li> 42 <img src="image/rabbit.jpg" alt=""> 43 <span>兔子</span> 44 </li> 45 <li> 46 <img src="image/duck.jpg" alt=""> 47 <span>鸭子</span> 48 </li> 49 </ul> 50 </body> 51 </html>
查看效果:
上面的图片,我们可以清楚的看到,右上没有顶端对齐,下面我们加入:vertical-align: top;垂直顶端对齐。代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 ul{ 8 margin: 0px; 9 padding: 0px; 10 width: 245px; 11 background-color: yellow; 12 border: 1px solid black; 13 } 14 img{ 15 width: 100px; 16 height: 100px; 17 border: 1px solid black; 18 } 19 li{ 20 display: inline-block; 21 vertical-align: top; 22 list-style: none; 23 width: 100px; 24 text-align: center; 25 font-family: SimHei; 26 margin: 0px 10px; 27 font-size:14px; 28 line-height: 20px; 29 } 30 </style> 31 </head> 32 <body> 33 <ul> 34 <li> 35 <img src="image/duck.jpg" alt=""> 36 <span>我是一只来自俄罗斯的可达鸭子</span> 37 </li> 38 <li> 39 <img src="image/tuttle.jpg" alt=""> 40 <span>乌龟</span> 41 </li> 42 <li> 43 <img src="image/rabbit.jpg" alt=""> 44 <span>兔子</span> 45 </li> 46 <li> 47 <img src="image/duck.jpg" alt=""> 48 <span>鸭子</span> 49 </li> 50 </ul> 51 </body> 52 </html>
显示效果:
其实,有一个小问题,当我们把li里面的margin: 0px 10px;去掉的时候,就会发现display:inline-block其实会有空隙的。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 ul{ 8 margin: 0px; 9 padding: 0px; 10 width: 245px; 11 background-color: yellow; 12 border: 1px solid black; 13 } 14 img{ 15 width: 100px; 16 height: 100px; 17 border: 1px solid black; 18 } 19 li{ 20 display: inline-block; 21 vertical-align: top; 22 list-style: none; 23 width: 100px; 24 text-align: center; 25 font-family: SimHei; 26 font-size:14px; 27 line-height: 20px; 28 } 29 </style> 30 </head> 31 <body> 32 <ul> 33 <li> 34 <img src="image/duck.jpg" alt=""> 35 <span>我是一只来自俄罗斯的可达鸭子</span> 36 </li> 37 <li> 38 <img src="image/tuttle.jpg" alt=""> 39 <span>乌龟</span> 40 </li> 41 <li> 42 <img src="image/rabbit.jpg" alt=""> 43 <span>兔子</span> 44 </li> 45 <li> 46 <img src="image/duck.jpg" alt=""> 47 <span>鸭子</span> 48 </li> 49 </ul> 50 </body> 51 </html>
显示效果:
由上图,我们可以明显的看到,display:inline-block产生了明显的空隙;我们可以采用一种方法,来处理一下;就是在包含块(ul)上设置font-size:0来解决;下面,来看一下代码吧。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>float练习</title> 6 <style type="text/css"> 7 ul{ 8 margin: 0px; 9 padding: 0px; 10 width: 245px; 11 background-color: yellow; 12 border: 1px solid black; 13 font-size: 0px; 14 } 15 img{ 16 width: 100px; 17 height: 100px; 18 border: 1px solid black; 19 } 20 li{ 21 display: inline-block; 22 vertical-align: top; 23 list-style: none; 24 width: 100px; 25 text-align: center; 26 font-family: SimHei; 27 font-size:14px; 28 line-height: 20px; 29 } 30 </style> 31 </head> 32 <body> 33 <ul> 34 <li> 35 <img src="image/duck.jpg" alt=""> 36 <span>我是一只来自俄罗斯的可达鸭子</span> 37 </li> 38 <li> 39 <img src="image/tuttle.jpg" alt=""> 40 <span>乌龟</span> 41 </li> 42 <li> 43 <img src="image/rabbit.jpg" alt=""> 44 <span>兔子</span> 45 </li> 46 <li> 47 <img src="image/duck.jpg" alt=""> 48 <span>鸭子</span> 49 </li> 50 </ul> 51 </body> 52 </html>
显示效果:
通过这样的处理,我们可以看到,图片之间的空隙消失了。