沙漠中的绿洲2019

导航

 

float属性,会使元素向左或向右移动,其周围的元素也会重新排列。float不仅自己飘忽不定,还对周围元素有影响,这种影响力不容小觑。他捉摸不定(浮动规律不好把握),他干涉他国内政(对周围元素有影响),这些特点就像今天的美国总统特朗普(别名“特不靠谱”)。学习float就得了解它的前世今生,它的本质,掌握它的规律才能降妖除魔,为我所用。

一、float的前世今生

          float设计之初,目的就是图文环绕

如果float一直踏踏实实、本本分分的干好本职工作,那他就是一个“好人”。float本该“不忘初心,牢记使命”,就像我们党开展的教育活动那样,可是他后来忘记了自己的初衷,竟参与到网页布局中,一度还乐此不疲,甚至受到一些程序员青睐。

          最早的网页布局很简单,元素的排列就是靠table、tr、td这样一些标签,页面很简单,float就是用来做图文环绕的,但是后来程序员发现float用在布局上也不错,打破了tabel(tr、td)标签死板的布局方式,float布局更加灵活多样。这样float就开始了“华丽转身”,正式成为网页布局中的一员大将。

          其实,float有很多毛病,他的浮动规律让很多人摸不着头脑,而且周围元素经常受到影响,稍有不慎原有的排布会支离破碎,所以有人说他是“魔鬼”,说他是“混球”,说他是“不务正业”,说他“跨界太大”,一点也不为过。

随着浏览器版本的升级,float在布局方面的作用逐渐被取代,但是,由于float的兼容性好,尽管他有很多问题,人们还是(不得不)包容他,在研究浮动规律的基础上,驾驭他、降伏他、利用他。

二、float的浮动规律

(一)float的本质

1、包裹性(与inline-block\block对比)

          包裹性就是在未设定宽度的情况下,根据内容自适应(也可以叫“自收缩”)。如下图:

 

 

具有包裹性的还有display:inline-block、position:absolute、position:fixed等。

 

在布局上float与inline-block很相似,如下图:

 

 

 

 

虽然很相似,但是仔细观察上图还是有些差别,比如li之间的缝隙,inline-block中间有缝,float中间没缝,在实际布局中,一般都希望中间没缝,这样便于计算尺寸。所以,float在这方面有先天优势(float能去空格,严丝合缝适合网页布局,通常把float布局叫做“码砖头”)。当然,如果你不介意中间的缝隙,或者采用一些办法去掉缝隙,也可以采用inline-block,实际情况下,如果代码稍微复杂些,inline-block可能还会出现垂直对齐(vertical-align)的问题,到时你可以查阅一些资料来解决问题。

 

不要以为floatinline-block比较相似,就以为浮动元素的显示方式(display)就是inline-block,实际上,浮动元素的显示方式(display)是block,确切地说是“通常情况下,浮动元素displayblock”,有些情况虽然不是block,比如displaylist-item,本质上也和block差不多。

 

下图,span元素本来是内联元素(displayinline)浮动(floatleft)后,我们通过浏览器右键的“审查元素”可以看到displayblock

 

这样,行内元素(比如span标签、a标签)和块元素(比如div标签)一旦浮动后都是一样的效果了,就是说<div style=”float:left;background:#ccc”>浮动元素</div><span style=”float:left;background:#ccc”>浮动元素</span>是完全一样的。这时再加上display属性就多余了,加上display属性(比如display:inline)浏览器也不会采用,纯属画蛇添足。

 

有人就问了“多个浮动元素可以水平排列在同一行,而浮动元素display:block就应该独占一行呀!,这不是互相矛盾吗?”,你看到上图中的那个词语了吗?“特殊”的块元素。因为浮动元素脱离了文档流(标准流),此时的块元素(displayblock)已不是标准流中的块元素了,它自收缩(包裹性),不再占用整行宽度,所以多个浮动元素可以水平排列在同一行。

 

补充一点,浮动元素“脱离标准流”,这里的“脱离标准流”和position:absolute脱离标准流不太一样,float的脱离标准流,在自由度上受限,不是自由翱翔的那种,而absolute脱离标准流是可以满世界乱跑的那种,自由度很大。所以,有的资料中不认可“浮动元素脱离标准流”的说法。本文不过于追究细节,笼统地说“浮动元素脱离标准流”,读者可以粗略这么理解。

 

2、破坏性

 

          破坏性,就是打破规则,并且影响周围元素。就像特朗普不断退群,不断修改规则,尽管让别的国家不知所措,对美国心生怨恨,但碍于美国实力,只能忍气吞声。

 

本文第一张图的第一部分,图片浮动前和文字基线对齐,在一行显示,图片高度比文字高,所以图片所在的这行跟别的(纯文字)行就不一样,这行显得很高,其实就是图片给撑起来的。

 

图片浮动(floatleft)后,以往的规则打破了,它像一副躯壳一样向左移动,它和文字不再基线对齐,打破了原有的规则。破坏性不仅表现在对齐方式的改变,还表现在父元素的高度塌陷上(子元素在浮动前要向父元素汇报高度,父元素把所有子元素的高度收集到后就确定了自己的高度,子元素浮动后,就不再向父元素汇报高度了,因此父元素收集不到子元素的高度就导致自己的高度塌陷)。

 

 

(二)浮动规则

1、图文环绕可以推广为:行内级内容会被浮动元素推出去(行内级内容包括行内级元素、inline-block元素、块级元素的文字内容)

 

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>test</title>
 8 </head>
 9 <style>
10     .floatDiv{
11         float:left;width:200px;height:200px;background:purple;color:#fff;
12     }
13     .inlineElement{
14         background:orange;padding:0 10px;
15     }
16     .inlineBlockElement{
17         display:inline-block;background:red;height:30px;width:130px;
18     }
19 </style>
20 <body>
21     <div class="floatDiv">浮动元素</div>
22     
23     <span class="inlineElement">行内元素</span>
24     <span class="inlineElement">行内元素</span>
25     <span class="inlineElement">行内元素</span>
26     <span class="inlineElement">行内元素</span>
27     <span class="inlineElement">行内元素</span>
28     <span class="inlineElement">行内元素</span>
29     <span class="inlineElement">行内元素</span>
30     <span class="inlineElement">行内元素</span>
31     <span class="inlineElement">行内元素</span>
32     <span class="inlineElement">行内元素</span>
33     
34     <div class="inlineBlockElement">inline-block元素</div>
35     <div class="inlineBlockElement">inline-block元素</div>
36     <div class="inlineBlockElement">inline-block元素</div>
37     <div class="inlineBlockElement">inline-block元素</div>
38     <div class="inlineBlockElement">inline-block元素</div>
39     <div class="inlineBlockElement">inline-block元素</div>
40     <div class="inlineBlockElement">inline-block元素</div>
41     
42     <div style="background:green;width:800px;height:400px;">
43         浮动元素脱离文档流,div(块元素)与浮动元素有重叠,但是div(块元素)里的文字,依然环绕在浮动元素周围。
44         浮动元素脱离文档流,div(块元素)与浮动元素有重叠,但是div(块元素)里的文字,依然环绕在浮动元素周围。    浮动元素脱离文档流,div(块元素)与浮动元素有重叠,但是div(块元素)里的文字,依然环绕在浮动元素周围。
45     </div>
46 </body>
47 </html>
View Code

 

提示读者,操作时注意调整浏览器的宽度

 

2、浮动元素只能在当前行中移动(floatleft,从右向左移动 floatright相反),遇到包含块(父元素)或其他浮动元素的边界为止。如果水平方向剩余的空间不够显示,浮动元素将向下移动,直到有足够的空间位置为止。

 

下面的代码

 

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>code2</title>
 8 </head>
 9 
10 <body>
11     这是第一部分文字,如果浏览器的宽度较小,这段文字会在图片的上方
12     <img src="img/pic1.jpg" style="float:left;">
13     <span style="color:#000;">第二部分文字,其他内容,其他内容,其他内容,其他内容(更多内容在此省略)</span>
14 </body>
15 </html>
View Code

在浏览器宽度较大时,第一部分文字和第二部分文字都在图片右侧排列

 

在浏览器宽度较小时,第一部分文字在图片的上方排列

下面的代码是几个div浮动后排布的情况

 

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>test</title>
 8 </head>
 9 <style>
10     .box1{width:200px;height:400px;background:blue;}
11     .box2{width:300px;height:300px;background:yellow;}
12     .box3{width:400px;height:200px;background:purple;}
13     .box4{width:100px;height:500px;background:red;}
14     .box5{width:500px;height:400px;background:green;}
15     .box6{width:500px;height:100px;background:gray;}
16     .box7{width:100px;height:400px;background:orange;}
17     .box8{width:400px;height:400px;background:#ccc;}
18     div{float:left;}
19 </style>
20 <body>
21     <div class="box1">box1</div>
22     <div class="box2">box2</div>
23     <div class="box3">box3</div>
24     <div class="box4">box4</div>
25     <div class="box5">box5</div>
26     <div class="box6">box6</div>
27     <div class="box7">box7</div>
28     <div class="box8">box8</div>
29 
30 </body>
31 </html>
View Code

代码结构:八个div都是floatleftbox1box8依次,尽管浏览器宽度不同时,浮动元素排布的结果不同,但是都遵循一定的规则,请看下图

 

 

 

 

 

为了说明问题,稍微删减部分divdiv仍然都是floatleftdiv的宽、高有所调整

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>code4</title>
 8 </head>
 9 <style>
10     .box1{width:400px;height:100px;background:blue;}
11     .box2{width:100px;height:500px;background:yellow;}
12     .box3{width:300px;height:200px;background:purple;}
13     .box4{width:300px;height:300px;background:red;}
14     .box5{width:300px;height:300px;background:green;}
15     div{float:left;}
16 </style>
17 <body>
18     <div class="box1">box1</div>
19     <div class="box2">box2</div>
20     <div class="box3">box3</div>
21     <div class="box4">box4</div>
22     <div class="box5">box5</div>
23 
24 </body>
25 </html>
View Code

 

由以上图可见,浮动元素的排列有相当严格的等级制度,后浮动的元素只能与前面的浮动元素在同一水平线上(以顶部为准),前提是后面的空间足够大。如果后面的空间不够,就会向下错位,错位后如果没有遇到阻力,还是水平移动(floatleft从右向左移动,floatright相反),移动过程中不会再上移动,水平移动直到遇到阻力,永远不会出现后面的浮动元素高于前面的浮动元素(以顶部为准)。就是说,后浮动的元素要么与前面的浮动元素平起平坐(顶部在同一水平线上),前提是后面的空间足够大;如果后面的空间不够,后浮动的元素只能处于下层,永远不会出现“僭越”,等级森严!

 

三、清除浮动

 

float是魔鬼,是混球,是黑恶势力,清除浮动就是“降妖除魔”,就是“扫黑除恶”。

 

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>code5</title>
 8 </head>
 9 <style>
10     .wrap{background:red;}
11     .wrap:after{display:block;content:'';clear:both;}
12     .content{float:left;width:300px;height:100px;}
13     .content1{background:lightblue;}
14     .content2{background:lightgreen;}
15     .content3{background:darkblue;}
16     
17     
18     .footer{height:50px;background:#ccc;}
19 </style>
20 <body>
21     <div class="wrap">
22         <div class="content content1"></div>
23         <div class="content content2"></div>
24         <div class="content content3"></div>
25     </div>
26     <div class="footer">footer</div>
27 </body>
28 </html>
View Code

 

方法1、增加一个额外的divclearboth

 

<div class="wrap">

 

                     <div class="content content1"></div>

 

                     <div class="content content2"></div>

 

                     <div class="content content3"></div>

 

 

 

                     <div style=”clear:both;”></div>

 

</div>

 

<div class="footer">footer</div>

 

这种方法就是相当于加了一个防火墙(防魔墙),打了一个隔板,但是因为增加了额外标签,可读性不强,所以不怎么推荐。

 

方法2、在父元素(class=”wrap”)填加属性overflow:hidden

 

.wrap{overflow:hidden;}

 

这种方法的解释,很难用一句话两句哈说清楚,所以本文不解释理由,这种方法兼容性也还可以,所以推荐使用。

 

方法3、使用父元素的伪类选择器

 

.wrap:after{display:block;content:””;clear:both;}

 

这跟方法1的道理差不多,但是没有增加额外标签,兼容性也还可以,所以推荐使用。

 

四、float的未来命运

 

我们使用float浮动做了很多其本职工作以外的事情。目前用float实现的不管是分栏布局,还是列表排列,我们都可以用其他一些CSS属性代替实现,唯一一个实现不了的就是“文字环绕图片”。未来,float可能会再回到老本行,只做图文环绕,把网页布局交给其他属性,也就是说float可能会退出网页布局的历史舞台。但那是将来的事,如果你对浏览器的兼容性有较高要求,你还不得不掌握它的浮动规律。

posted on 2020-09-01 16:43  沙漠中的绿洲2019  阅读(372)  评论(0编辑  收藏  举报