本文介紹了四種清除浮動的方法,並嘗試解釋其原理。在理解了各類清除浮動的原理以後,你會發現,不少清除浮動的方法本質上實際上是同樣的。掌握這些原理,相信你能夠根據場景和需求,靈活運用原則發展出不一樣的清除浮動的方法,而再也不死記或拘泥於文中提到的方法。css
在講清除浮動的方法以前,咱們先來了解一下爲何要清除浮動,清除浮動的目的是什麼,即,要解決什麼樣的問題。來看一個浮動的例子(略去了文字內容):html
<div class="topDiv"> <div class="floatDiv">float left</div> <div class="textDiv">...</div> </div> <div class="bottomDiv">...</div>複製代碼
其樣式爲:chrome
.topDiv { width: 500px; border: 2px solid black; } .floatDiv { width: 100px; height: 100px; border: 2px dotted red; color: red; margin: 4px; float: left; } .bottomDiv { width: 500px; height: 100px; margin: 5px 0; border: 2px dotted black; } .textDiv { color: blue; border: 2px solid blue; }複製代碼
在chrome中渲染的效果以下圖所示:瀏覽器
這確定不是咱們想要的渲染效果,它可能存在以下問題:markdown
.textDiv
)排列在浮動元素下方,或者,咱們並不但願.textDiv
兩邊有浮動元素存在。.topDiv
),父元素的高度出現了塌縮,若沒有文字高度的支撐,不考慮邊框,父級元素高度會塌縮成零。.bottomDiv
)排版。由於浮動元素脫離了文檔流,.bottomDiv
在計算元素位置的時候會忽略其影響,緊接着上一個元素的位置繼續排列。解決第一個問題,須要清除.textDiv
周圍的浮動,而解決第二個問題,由於父元素的兄弟元素位置只受父元素位置的影響,就須要一種方法將父級元素的高度撐起來,將浮動元素包裹在其中,避免浮動元素影響父元素外部的元素排列。ide
接下來開始介紹清除浮動的方法。工具
仍是開篇的例子,咱們給須要清除浮動的元素添加以下樣式:oop
.textDiv {
color: blue;
border: 2px solid blue;
clear: left;
}複製代碼
清除浮動後的渲染效果以下:性能
解釋一下:學習
經過上面的樣式,.textDiv
告訴瀏覽器,個人左邊不容許有浮動的元素存在,請清除掉我左邊的浮動元素。然而,由於浮動元素(.floatDiv
)位置已經肯定,瀏覽器在計算.textDiv
的位置時,爲知足其需求,將.textDiv
渲染在浮動元素下方,保證了.textDiv
左邊沒有浮動元素。同時能夠看出,父元素的高度也被撐起來了,其兄弟元素的渲染也再也不受到浮動的影響,這是由於.textDiv
仍然在文檔流中,它必須在父元素的邊界內,父元素只有增長其高度才能達到此目的,能夠說是一個意外收穫。(clear
的值爲both
也有相同的效果,通俗理解就是,哪邊不容許有浮動元素,clear就是對應方向的值,兩邊都不容許就是both
)
可是,若是咱們把HTML中的.floatDiv
和.textDiv
交換一下位置呢?
<div class="topDiv"> <div class="textDiv">...</div> <div class="floatDiv">float left</div> </div> <div class="bottomDiv">...</div>複製代碼
不管.textDiv
是否應用清除浮動,狀況都是下面的樣子:
.textDiv
的位置先肯定了,因而浮動元素就緊接着.textDiv
下方渲染在父元素的左側。然而,父元素的高度並無被撐起來,沒有將浮動影響「內化」,致使浮動影響到了接下來的元素排版。
看來,爲達到撐起父元素高度的目的,使用clear
清除浮動的方法仍是有適用範圍的。咱們須要更加通用和可靠的方法。
(這裏澄清一下,單從元素清除浮動的角度,clear
徹底已經達到了目的,它已經使得.textDiv
特定的方向上再也不有浮動元素,清除浮動其實僅僅針對須要清除浮動的元素自己而言,只關注自身需求是否達到,和外界沒有什麼關係,它不關注浮動是否超出父元素,以及浮動是否影響到後續元素排列。咱們只是利用了浮動的一些特性達到某些目的,但這不是清除浮動關心的問題,只不過,相對於清除浮動,咱們可能更加關心這些特性能爲咱們作些什麼而已。個人理解是,清除浮動和撐起父元素高度實際上是兩個不一樣的問題,在這裏,能夠簡單地理解爲工具和目的之間的關係,接下來要討論的兩個方法都是在利用清除浮動這個工具在解決問題,它並非清除浮動這個工具自己。不過,咱們常常將二者混爲一談。sorry,有點囉嗦,看不懂就是我沒表達清楚,跳過便可。。。)
HTML結構以下,在有浮動的父級元素的末尾插入了一個沒有內容的塊級元素div:
<div class="topDiv"> <div class="textDiv">...</div> <div class="floatDiv">float left</div> <div class="blankDiv"></div> </div> <div class="bottomDiv">...</div>複製代碼
應用樣式:
.topDiv { width: 500px; border: 2px solid black; } .floatDiv { width: 100px; height: 100px; border: 2px dotted red; color: red; margin: 4px; float: left; } .bottomDiv { width: 500px; height: 100px; margin: 5px 0; border: 2px dotted black; } .textDiv { color: blue; border: 2px solid blue; } // 區別在這裏 .blankDiv { clear: both; // or left }複製代碼
渲染效果以下:
原理無需多講,和第一個例子裏.textDiv
應用clear清除浮動,撐起父級元素高度的原理徹底同樣。這裏強調一點,即,在父級元素末尾添加的元素必須是一個塊級元素,不然沒法撐起父級元素高度。
HTML結構以下,爲了慣例相符,在.topDiv
的div上再添加一個clearfix
類:
<div class="topDiv clearfix"> <div class="textDiv">...</div> <div class="floatDiv">float left</div> </div> <div class="bottomDiv">...</div>複製代碼
樣式應用以下:
// 省略基本的樣式 // 區別在這裏 .clearfix:after { content: '.'; height: 0; display: block; clear: both; }複製代碼
該樣式在clearfix
,即父級元素的最後,添加了一個:after
僞元素,經過清除僞元素的浮動,達到撐起父元素高度的目的。注意到該僞元素的display
值爲block
,即,它是一個不可見的塊級元素(有的地方使用table
,由於table
也是一個塊級元素)。你可能已經意識到,這也只不過是前一種清除浮動方法(添加空白div)的另外一種變形,其底層邏輯也是徹底同樣的。前面的三種方法,其本質上是同樣的。
首先直觀地看看,overflow
是如何清除浮動的。
HTML結構以下:
<div class="topDiv"> <div class="floatDiv">float left</div> <div class="textDiv">...</div> </div> <div class="bottomDiv">...</div>複製代碼
樣式應用以下:
.topDiv { width: 500px; padding: 4px; border: 2px solid black; // 區別在這裏 overflow: auto; } .floatDiv { width: 100px; height: 100px; border: 2px dotted red; color: red; margin: 4px; float: left; } .bottomDiv { width: 500px; height: 100px; margin: 5px 0; border: 2px dotted black; clear: both; } .textDiv { color: blue; border: 2px solid blue; }複製代碼
不該用上面標識出來的CSS時,渲染結果和本文開始的第一個圖形效果相同,應用CSS後的渲染效果以下:
僅僅只在父級元素上添加了一個值爲auto的overflow屬性,父元素的高度當即被撐起,將浮動元素包裹在內。看起來,浮動被清除了,浮動再也不會影響到後續元素的渲染(嚴格講,這和清除浮動沒有一點關係,由於不存在哪一個元素的浮動被清除,不糾結這個問題)。其實,這裏的overflow值,還能夠是除了"visible"以外的任何有效值,它們都能達到撐起父元素高度,清除浮動的目的。不過,有的值可能會帶來反作用,好比,scroll值會致使滾動條始終可見,hidden會使得超出邊框部分不可見等。那它們是如何作到浮動清除的呢?
要講清楚這個解決方案的原理,有一個概念始終是繞不過去,那就是塊格式化上下文(BFC),然而這又是一個很是抽象的概念,若是要清楚地把這個概念講出來,恐怕須要很是大的篇幅,這裏僅說起和理解該問題相關的內容。
這是從MDN上摘下來的BFC定義:
A block formatting context is a part of a visual CSS rendering of a Web page. It is the region in which the layout of block boxes occurs and in which floats interact with each other.
翻譯過來就是:塊級格式化上下文是CSS可視化渲染的一部分。它是一塊區域,規定了內部塊盒的渲染方式,以及浮動相互之間的影響關係。
塊格式化上下文(BFC)有下面幾個特色:
有了這幾點,就能夠嘗試解釋爲何overflow
(值不爲visible
)能夠清除浮動了。
當元素設置了overflow
樣式,且值不爲visible
時,該元素就建構了一個BFC(哪些狀況下,元素能夠建構出BFC,能夠看查看CSS文檔對BFC的定義)。在咱們的例子中,.topDiv
因設置了值爲auto
的overflow
樣式,因此該元素建構出一個BFC,按照第三個特色,BFC的高度是要包括浮動元素的,因此.topDiv
的高度被撐起來,達到了清除浮動影響的目的。(至於爲何值爲visible
的overflow
不能建構BFC,這個答案給了一個解釋)
其實,這裏overflow的做用就是爲了構建一個BFC區域,讓內部浮動的影響都得以「內化」。若是你看了BFC的定義,你會發現,構建一個BFC區域的方法有不少種,overflow
只是其中的一種,那在這裏,咱們是否也能夠利用其它的方式構建BFC,且一樣能達到清除浮動的目的呢?
BFC定義中說,inline-block
一樣也能構建BFC,那咱們就用該樣式來試試:
.topDiv {
width: 500px;
padding: 4px;
border: 2px solid black;
// 區別在這裏
display: inline-block;
}
// 其餘樣式相同,省略複製代碼
渲染效果以下:
效果徹底同樣!只要咱們理解了原理,就能夠靈活演變出不一樣的清除浮動的方法,而沒必要死記某種手段。
固然,要說明的是,在實際項目中選擇採用哪一種方式構建BFC是要具體問題具體分析的,由於要考慮到選用的樣式自身的做用和影響。這個例子中,選用inline-block
和選用overflow
效果徹底同樣,沒有看出有什麼反作用,但不表明在其餘項目中同樣能行得通。甚至對overflow
值的選擇也要考慮其表現和影響。在各類構建BFC的方式中,overflow
方式多是外部影響更可控的一種,我猜測這也許就是爲何廣泛採用overflow
來清除浮動的緣由吧。
到這裏,我要分享的清除浮動的方法已經講完了。其實,若是在不一樣的使用場景下,對這幾個方法進行拆分組合(實際上是對底層原理的拆分組合),還能夠實現其餘形式不一樣的清除浮動的方法,最重要的仍是對底層原理的把握。知其然,亦知其因此然纔是最有效的學習方式。
下面是文中涉及的連接彙總:
水平有限,文章中不免會出現不許確,甚至錯誤的地方,期待你的寶貴意見!