CSS 深入理解之 float 浮動

發表於2018-05-25

float屬性是CSS中常用的一個屬性,在實際工作中使用的非常多,如果使用不當就會出現意料之外的效果。雖然很多人說浮動會用就行、浮動過時了,但是對於優秀的前端開發人員,需要有”刨根問底”的精神,這樣在出現一些問題的時候才不至於”手慌腳亂”!因此,今天就特別整理和總結一下float屬性。

1. float介紹

CSS世界中的float屬性是一個年代非常久遠的屬性,設定了float屬性的元素會根據設定的屬性值向左或者向右浮動,直到它的外邊緣碰到包含框或另一個浮動框的邊框為止。設定了float屬性的元素會從普通文件流中脫離,相當於不佔據任何空間,所以文件中普通流中的元素表現的就像浮動元素不存在一樣,因此,設定float屬性的後會影響我們的頁面佈局。具體說來就是:讓block元素無視float元素,讓inline元素像流水一樣圍繞著float元素實現浮動佈局

float屬性設計的初衷:僅僅是讓文字像流水一樣環繞浮動元素,就像下圖中展示的一樣:

CSS 深入理解之 float 浮動

2. float的特性

float有哪些有意思的特性呢?具體如下:

  • 包裹性
  • 高度塌陷
  • 塊狀化
  • 沒有任何margin合併

下面將詳細闡述這幾點的含義。

2.1 包裹性

所謂”包裹性”,其實是由”包裹”和”自適應”兩部分組成。假設有以下CSS程式碼:

1)包裹。本例中將浮動元素父元素寬度設定為200px,浮動元素的子元素是一個128px寬度的圖片,則此時浮動元素寬度表現為”包裹”,也就是裡面圖片的寬度128px。

 3690013586-5addce853f5e0_articlex

 

2)自適應性。在浮動子元素的中增加一些文字:

此時,浮動元素寬度就自適應父元素的200px寬度,最終的寬度表現也是200px。如下圖所示:

4139378965-5addd23fb9ccf_articlex

2.2 高度塌陷

float屬性有一個著名的特性:會讓父元素的高度塌陷。如章節2.1中的效果圖,父元素div的高度並沒有被子元素撐開(粉色區域),這種效果可以稱為”高度塌陷“。導致高度塌陷的原因是因為浮動元素脫離了正常的文件流,則div.father認為其沒有子元素,所以產生了高度塌陷。後文中將講述如何解決高度塌陷的問題。

2.3 塊狀化

塊狀化的意思是,一旦元素float的屬性不為none,則其display計算值就是block或者table。舉個例子:

在控制檯中的結果如下:

不知道大家有沒有跟我一樣的疑問:既然設定float後,元素就塊狀化了,那麼怎麼還能產生包裹性的效果呢?回答這個問題,需要重新闡述下塊狀化的意思,這裡的塊狀化意思是可以像block元素一樣設定寬和高,並不是真正的塊元素。

因此,沒有任何理由出現下面的樣式組合:

2.4 沒有任何的margin重疊

在這裡,我們將.son類增加margin:10px樣式,在瀏覽器中檢視實際效果。

39060460-5addd255ae994_articlex

我們增加.son類的margin為10px,在瀏覽器中檢視相鄰的.son元素的空白區域的高度是20px,可以發現設定了float屬性的元素沒有任何的margin重疊,這和普通的元素margin重疊不一樣。

3. float與流體佈局

使用float可以通過破壞正常的文件流實現CSS環繞,但是卻帶來了”高度塌陷”的問題!然而我們可以利用float破壞正常文件流的特性實現一些常用的佈局:

  • 文字環繞變身-中間內容居中,左中右佈局

直接看例子:

從下圖中看出,實現了中間內容居中的左中右佈局。

106556438-5addd268befe1_articlex

  • 文字環繞的衍生-單側固定

和文字環繞效果相比,區別就是.girl多了一個margin-left: 70px,同時圖片的寬度設定60px,因此不會發生文字環繞的效果。這裡,我們也可以不使用margin-left,改用border-left或者padding-left都可以達到改變content box的尺寸,從而實現寬度自適應佈局效果。

395086395-5addd27c4695a_articlex

4. float的剋星

既然使用float屬性會帶來一系列的問題,那麼有沒有辦法消除這些問題呢?答案是:肯定有。接著看下文。

4.1 clear屬性

在CSS中可以使用clear來清除float屬性帶來高度塌陷等問題,使用格式如下:

  • none:預設值,允許兩邊都有浮動物件;
  • left:不允許左側有浮動物件;
  • right:不允許右側有浮動物件;
  • both:兩側不允許有浮動物件。

如果單從字面上的意思來理解,clear:left應該是”清除左浮動“,clear:right應該是”清除右浮動“,實際上,這種說法是有問題的,因為浮動一直還在,並沒有清除!只能清除浮動帶來的影響。

官方對clear屬性的解釋是:“元素盒子的邊不能和前面的浮動元素相鄰”。注意這裡的”前面的”3個字,也就是clear屬性對”後面的”浮動元素是不聞不問的。clear屬性只能清除元素的自身,不能影響其他的元素。接著看下面的這個例子:

3225577221-5addd29ba1166_articlex

如上圖所示,box1元素為設定了左浮動,已經脫離了正常的文件流,所以box2能夠在box1的底層顯示。如果想讓box2能夠換行排列,則只需要在.box2類中增加clear:left樣式即可。如下圖所示:

306925660-5addd2ac5e8ee_articlex

4.2 clear屬性的不足

clear屬性只對塊級元素有效,但是::after等偽元素預設都是內聯水平,因此,在實際工作中,我們常常使用下面的程式碼來清除浮動帶來的影響:

由於clear:both作用的本質是讓自己不和float元素在一行顯示,並不是真正意義上的清除浮動,因此float元素有一些不好的特性依然存在,表現在:

  • 如果clear:both元素前面的元素就是float元素,則設定margin-top無效;

在本例中,設定.box2中的margin-top沒有任何的效果,如下圖所示:
2644755153-5addd2bf47e30_articlex

  • clear:both後面的元素依舊可能會發生文字環繞現象。

在本例中,設定clean:both來阻止浮動對後面元素的影響,但是最後的錯位效果依然發生了(可以設定.father的字型大小為0,然後設定p標籤的字型大小解決錯誤的問題)。

2175187666-5addd2d64470e_articlex

由此可見,clear:both只能在一定程度上消除浮動的影響,要想完美去除浮動元素的影響,藉助其他的手段——BFC,接著看下文。

5. CSS世界的結界——BFC

5.1 BFC的定義

BFC全稱block formatting context,中文為”塊級格式化上下文“。BFC的表現原則為:如果一個元素具有BFC,那麼它的內部子元素再怎麼翻江倒海,都不會影響外部的元素。因此,BFC元素是不可能發生margin重疊的,另外,BFC元素也可以用來清除浮動的影響。

那麼滿足什麼條件才會有BFC呢?只要滿足下面任意一個條件就會觸發BFC:

  • html根元素;
  • float的值不為none;
  • overflow的值為auto、scroll或者hidden;
  • display的值為table-cell、table-caption和inline-block中的任何一個;
  • position的值不為relative和static;

觸發BFC後,就不需要使用clear:both屬性去清除浮動的影響。

5.2 BFC的作用

  • 清除margin重疊

在這種情況下,出現了margin重疊的效果。如下圖所示:

1675603688-5addd2e94d8dc_articlex

利用BFC能消除margin重疊,謹記:只有當元素在同一個BFC中時,垂直方向上的margin才會clollpase。如果它們屬於不同的BFC,則不會有margin重疊。因此我們可以再建立一個BFC去阻止margin重疊的發生。所以為了讓他們的margin變成20px,我們只需要用div,建立一個BFC,令p元素處於不同BFC即可。請看例子:

從下圖中可以看出,藉助BFC消除了margin重疊的問題。

1817730249-5addd307f20cf_articlex

  • 清除高度塌陷的問題

在上面的章節中,如果子元素設定浮動屬性,則父元素就會出現高度塌陷的問題。在這裡,我們可以藉助BFC消除高度塌陷的問題了,請看下面的這個例子:

從下圖中可以看到,設定overflow:hidden樣式後就產生了BFC,根據BFC的表現規則,內部元素的樣式不會影響外部元素的樣式,因此沒有出現高度塌陷的問題。

710306655-5addd31bd3673_articlex

  • 自適應佈局(阻止文字換行)

如果我們給.girl元素設定具有BFC特性的屬性,如:overflow: hidden就可以實現更健壯、更智慧的自適應佈局。

1228574324-5addd3374b010_articlex

這裡的.girl元素為了不和浮動元素產生任何交集,順著浮動邊緣形成自己的封閉上下文。

普通元素在設定了overflow:hidden後,會自動填滿容器中除了浮動元素意外的剩餘空間,形成自適應效果,這種自適應佈局和純流體佈局相比:

  • 自適應內容由於封閉而更加健壯,容錯性更強;
  • 自適應內容能夠填滿除浮動元素以外區域,不需要關心浮動元素寬度。

6. 結語

本文是我學習float屬性總結文章,可能存在理解準確的地方,歡迎大家在評論區評論,指點迷津,大家互相幫助,互相進步。

最後,希望本文的內容能夠對您對float的理解能夠有所幫助,感謝閱讀。

參考

張鑫旭-《CSS世界》


作者簡介:

中文名:石頭
英文名:micstone
某電商平臺前端程式設計師一名,偶爾也寫寫後端程式碼,工作經歷2016.7~至今。

相關文章