1. 程式人生 > 實用技巧 >輕輕鬆鬆學CSS:float

輕輕鬆鬆學CSS:float

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)的問題,到時你可以查閱一些資料來解決問題。
不要以為float和inline-block比較相似,就以為浮動元素的顯示方式(display)就是inline-block,實際上,浮動元素的顯示方式(display)是block,確切地說是“通常情況下,浮動元素display:block”,有些情況雖然不是block,比如display:list-item,本質上也和block差不多。
下圖,span元素本來是內聯元素(display:inline)浮動(float:left)後,我們通過瀏覽器右鍵的“審查元素”可以看到display:block

這樣,行內元素(比如span標籤、a標籤)和塊元素(比如div標籤)一旦浮動後都是一樣的效果了,就是說浮動元素與浮動元素

是完全一樣的。這時再加上display屬性就多餘了,加上display屬性(比如display:inline)瀏覽器也不會採用,純屬畫蛇添足。
有人就問了“多個浮動元素可以水平排列在同一行,而浮動元素display:block就應該獨佔一行呀!,這不是互相矛盾嗎?”,你看到上圖中的那個詞語了嗎?“特殊”的塊元素。因為浮動元素脫離了文件流(標準流),此時的塊元素(display:block)已不是標準流中的塊元素了,它自收縮(包裹性),不再佔用整行寬度,所以多個浮動元素可以水平排列在同一行。
補充一點,浮動元素“脫離標準流”,這裡的“脫離標準流”和position:absolute脫離標準流不太一樣,float的脫離標準流,在自由度上受限,不是自由翱翔的那種,而absolute脫離標準流是可以滿世界亂跑的那種,自由度很大。所以,有的資料中不認可“浮動元素脫離標準流”的說法。本文不過於追究細節,籠統地說“浮動元素脫離標準流”,讀者可以粗略這麼理解。
2、破壞性
破壞性,就是打破規則,並且影響周圍元素。就像特朗普不斷退群,不斷修改規則,儘管讓別的國家不知所措,對美國心生怨恨,但礙於美國實力,只能忍氣吞聲。
本文第一張圖的第一部分,圖片浮動前和文字基線對齊,在一行顯示,圖片高度比文字高,所以圖片所在的這行跟別的(純文字)行就不一樣,這行顯得很高,其實就是圖片給撐起來的。
圖片浮動(float:left)後,以往的規則打破了,它像一副軀殼一樣向左移動,它和文字不再基線對齊,打破了原有的規則。破壞性不僅表現在對齊方式的改變,還表現在父元素的高度塌陷上(子元素在浮動前要向父元素彙報高度,父元素把所有子元素的高度收集到後就確定了自己的高度,子元素浮動後,就不再向父元素彙報高度了,因此父元素收集不到子元素的高度就導致自己的高度塌陷)。

(二)浮動規則
1、圖文環繞可以推廣為:行內級內容會被浮動元素推出去(行內級內容包括行內級元素、inline-block元素、塊級元素的文字內容)

`

test 浮動元素
<span class="inlineElement">行內元素</span>
<span class="inlineElement">行內元素</span>
<span class="inlineElement">行內元素</span>
<span class="inlineElement">行內元素</span>
<span class="inlineElement">行內元素</span>
<span class="inlineElement">行內元素</span>
<span class="inlineElement">行內元素</span>
<span class="inlineElement">行內元素</span>
<span class="inlineElement">行內元素</span>
<span class="inlineElement">行內元素</span>

<div class="inlineBlockElement">inline-block元素</div>
<div class="inlineBlockElement">inline-block元素</div>
<div class="inlineBlockElement">inline-block元素</div>
<div class="inlineBlockElement">inline-block元素</div>
<div class="inlineBlockElement">inline-block元素</div>
<div class="inlineBlockElement">inline-block元素</div>
<div class="inlineBlockElement">inline-block元素</div>

<div style="background:green;width:800px;height:400px;">
	浮動元素脫離文件流,div(塊元素)與浮動元素有重疊,但是div(塊元素)裡的文字,依然環繞在浮動元素周圍。
	浮動元素脫離文件流,div(塊元素)與浮動元素有重疊,但是div(塊元素)裡的文字,依然環繞在浮動元素周圍。	浮動元素脫離文件流,div(塊元素)與浮動元素有重疊,但是div(塊元素)裡的文字,依然環繞在浮動元素周圍。
</div>
` 提示讀者,操作時注意調整瀏覽器的寬度 2、浮動元素只能在當前行中移動(float:left,從右向左移動 float:right相反),遇到包含塊(父元素)或其他浮動元素的邊界為止。如果水平方向剩餘的空間不夠顯示,浮動元素將向下移動,直到有足夠的空間位置為止。 下面的程式碼 ` code2 這是第一部分文字,如果瀏覽器的寬度較小,這段文字會在圖片的上方 第二部分文字,其他內容,其他內容,其他內容,其他內容(更多內容在此省略) ` 在瀏覽器寬度較大時,第一部分文字和第二部分文字都在圖片右側排列 ![](https://img2020.cnblogs.com/blog/1777491/202009/1777491-20200901161135977-799240196.png) 在瀏覽器寬度較小時,第一部分文字在圖片的上方排列 ![](https://img2020.cnblogs.com/blog/1777491/202009/1777491-20200901161209994-79030210.png) 下面的程式碼是幾個div浮動後排布的情況 ` test box1 box2 box3 box4 box5 box6 box7 box8 ` 程式碼結構:八個div都是float:left,box1至box8依次,儘管瀏覽器寬度不同時,浮動元素排布的結果不同,但是都遵循一定的規則,請看下圖 ![](https://img2020.cnblogs.com/blog/1777491/202009/1777491-20200901161315393-488525526.png) 為了說明問題,稍微刪減部分div,div仍然都是float:left,div的寬、高有所調整 ` code4 box1 box2 box3 box4 box5 ` ![](https://img2020.cnblogs.com/blog/1777491/202009/1777491-20200901161407487-1831586977.png) 由以上圖可見,浮動元素的排列有相當嚴格的等級制度,後浮動的元素只能與前面的浮動元素在同一水平線上(以頂部為準),前提是後面的空間足夠大。如果後面的空間不夠,就會向下錯位,錯位後如果沒有遇到阻力,還是水平移動(float:left從右向左移動,float:right相反),移動過程中不會再上移動,水平移動直到遇到阻力,永遠不會出現後面的浮動元素高於前面的浮動元素(以頂部為準)。就是說,後浮動的元素要麼與前面的浮動元素平起平坐(頂部在同一水平線上),前提是後面的空間足夠大;如果後面的空間不夠,後浮動的元素只能處於下層,永遠不會出現“僭越”,等級森嚴! 三、清除浮動 float是魔鬼,是混球,是黑惡勢力,清除浮動就是“降妖除魔”,就是“掃黑除惡”。 ` code5 footer ` 方法1、增加一個額外的div(clear:both)
	<div style=”clear:both;”></div>
footer 這種方法就是相當於加了一個防火牆(防魔牆),打了一個隔板,但是因為增加了額外標籤,可讀性不強,所以不怎麼推薦。 方法2、在父元素(class=”wrap”)填加屬性overflow:hidden .wrap{overflow:hidden;} 這種方法的解釋,很難用一句話兩句哈說清楚,所以本文不解釋理由,這種方法相容性也還可以,所以推薦使用。 方法3、使用父元素的偽類選擇器 .wrap:after{display:block;content:””;clear:both;} 這跟方法1的道理差不多,但是沒有增加額外標籤,相容性也還可以,所以推薦使用。 四、float的未來命運 我們使用float浮動做了很多其本職工作以外的事情。目前用float實現的不管是分欄佈局,還是列表排列,我們都可以用其他一些CSS屬性代替實現,唯一一個實現不了的就是“文字環繞圖片”。未來,float可能會再回到老本行,只做圖文環繞,把網頁佈局交給其他屬性,也就是說float可能會退出網頁佈局的歷史舞臺。但那是將來的事,如果你對瀏覽器的相容性有較高要求,你還不得不掌握它的浮動規律。