理解CSS浮動與清除浮動

本文主要探討兩個問題:css

  1. 爲何CSS設置浮動會引發父元素塌陷html

  2. 爲何設置clear:both能清除浮動,並撐開父元素。前端

原由

CSS的浮動,算是我在寫網頁時用的最多的屬性之一。但要說我對浮動的瞭解程度的話,只能說「知其然而不知其因此然」。雖然不少人都說浮動會用就行,可是要想成爲一個優秀的前端,對這些經常使用屬性得知根知底。程序員

恰巧在慕課網,張鑫旭老師開了《CSS深刻理解之float浮動》這門課。連接在文末,有興趣的能夠聽聽,老師講課風格很風趣……web

Float的歷史

Float設計的初衷,是爲了實現文字環繞效果。就像下圖展現的同樣(圖片源於w3school):
Float效果圖
嗯,就這麼簡單。chrome

Float引發的父元素高度塌陷BUG?

在這兒,咱們用一個例子來講明子元素設置浮動,從而引發父元素高度塌陷的問題。
首先寫一個div,裏面插入一張圖片。學習

<div id="div">
  <img src="./source/head.jpg">
</div>

咱們再給div設置一個border,爲了讓你們看的清楚。
CSS設置以下:spa

#div {
  border: 5px solid red;
  width: 600px;
}

最後效果是這樣的:
未Float的效果圖
經過chrome控制檯,能夠看到此時div的高度爲464px。
div高度ssr

接下來,咱們給那張圖片添加浮動效果。設計

#div img{
  float: left;
}

再看網頁,發現父元素已經塌陷了,以前的邊框也消失不見了,成爲一條線了。
Float後的效果圖
此時再去控制檯查看div的高度,高度爲0px。
div高度

不,不是BUG

不少人把這個現象稱爲浮動帶來的BUG。但從一開始Float的用途來思考:

「Float設計的初衷,是爲了實現文字環繞效果。」

那麼,在那遠古蠻荒的互聯網時代,要如何實現文字環繞圖片的效果呢?機智的程序員加入了Float屬性,也引入了子元素浮動,父元素高度塌陷的特性。
看到這句話的時候,我思考了好久。由於沒法理解父元素高度塌陷爲什麼能讓文字環繞圖片。因而把視頻來來回回看了十多遍,又手寫了個demo,總算理解了。

總結來講,核心要點在於一句話:

「浮動元素會脫離文檔流。」

至於文檔流是啥,我這兒就不介紹了。但浮動的元素脫離了文檔流,因此是不計算高度的。
在此,咱們加入一段話,看看div的高度。
段落高度
從圖中能夠看出,div由於段落的加入,高度被撐開了。

因此子元素浮動引發父元素高度塌陷的緣由以下:
由於沒有預先設置div高度,因此div高度由其包含的子元素高度決定。而浮動脫離文檔流,因此圖片並不會被計算高度。此時的div中,至關於div中子元素高度爲0,因此發生了父元素高度塌陷現象。

文字環繞效果的實現

那麼,文字環繞效果是如何實現的?
其實講起來也很簡單,由於父元素高度塌陷,因此文字會按正常順序排列,無視圖片高度。而圖片寬帶又還在,因此實現了文字環繞效果。

清除浮動

介紹完浮動,天然要介紹清除浮動。在此,咱們不具體的去探討各類清除浮動的方式。而是去探討,爲什麼設置clear:both能清除浮動,並撐開父元素。

clear:both的做用

clear:both的做用,對各位來講能夠算是耳熟能詳了。至於clear的left,right等屬性,咱們這兒就不一一列舉了。

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

在父元素內的底部,加入這一行代碼。看圖易知,父元素由於子元素設置浮動而高度塌陷的問題,已經被解決了。
加入clear: both後的效果

而後若是隻是會用clear:both,又怎麼能知足個人求知慾呢?相比與這行代碼產生的做用,我更關心爲何這行代碼能清除浮動。
對此,我繼續翻閱文檔。
在w3school中,clear的定義以下:

clear 屬性規定元素的哪一側不容許其餘浮動元素。

固然,這樣看,仍是很難理解爲何clear能清除浮動並撐開父元素高度。那咱們舉個栗子!
當先聲明一個元素A向左浮動時,因爲脫離文檔流,這個元素的右邊就會空出一片空間,空間的長寬與浮動元素長寬相同。
而後咱們再聲明另一個元素B,若是元素A右側空出的空間內,還能放下元素B的話,那麼元素B就會自動補上去。
下面我寫一個demo,應該就很好理解了。
HTML部分以下:

<div id="div">
  <div id="a">
    <p>I'm divA</p> //此處用p
  </div>
  <div id="b">
    <span>I'm divB</span> //用span,防止兩個都是p,不能展示父元素塌陷效果。
  </div>
</div>

CSS部分以下:

#div {
  border:5px solid red;
  width:400px;
}
#a {
  background:rgba(149, 149, 149, 0.42); // 爲了方便演示,A的背景色設置成半透明。
  width:200px;
  float: left;
}
#b {
  background: #6EEBC1;
  width:300px;
}

效果圖長這樣:
demo效果

從圖上能夠看到,元素B的一部分是在元素A空出的空間內的。而且I'm divB這句話在元素A的右側。且父元素高度塌陷,父元素如今的高度就是元素B的高度。
那麼若是元素A右側空出的空間內,放不下元素B呢?
咱們把元素B寬度調整爲200px。

放不下時的效果
能夠看出,元素B就自成一行了。

給元素B加入clear:both後,元素B將忽略左邊浮動所產生的空間,不去補空缺。
元素B設置clear:both後
如圖所示,元素B會另起一行。而不是縮到浮動產生的空間內。

撐開父元素空間的奧祕

在w3school中,clear的定義中還有這麼一句話:

「在 CSS2.1 中,會在設置清除浮動的元素上外邊距之上增長清除空間,而外邊距自己並不改變。」

也就是說,由於浮動而產生的空白空間,會被填充爲實際存在的空間。。那麼,天然就能撐開父元素。

總結

總結下來,浮動與清除浮動的順序關係以下:

  1. 設置元素A浮動,元素脫離文檔流,不計算高度。父元素出現高度塌陷。

  2. 浮動元素A產生空白空間。空間長寬等於元素A的長寬。後面元素會自動補空缺。

  3. 給浮動元素以後的元素B設置clear:both,元素B將不去補空缺。

  4. 元素B不只不補空缺,還會把元素A因浮動而產生的空白空間填充爲實際空間。

  5. 實際空間被計算高度,父元素被撐開。

這麼一番走下來,花了不少時間去思考,去寫demo。但對CSS浮動的理解也加深了。浮動爲什麼引發父元素塌陷和清除浮動爲什麼能撐開父元素這兩個問題,一直是個人盲點。因此此次寒假,集中了兩天時間去攻克它(除夕和正月初一,大過年的寫代碼,感受有點怪但效率卻出奇的高……)。

參考連接:

《CSS深刻理解之float浮動》-- 張鑫旭(也是課程地址)
CSS clear 屬性
clear:both 爲何不起做用?--知乎,田雅文的回答

前端路漫漫,且行且歌。
最後附上本人博客地址和原文連接,但願能與各位多多交流。

Lxxyx的前端樂園
原文連接:寒假前端學習(8)——理解CSS浮動與清除浮動

相關文章
相關標籤/搜索