1.探究圖片環(huán)繞文字的傳說
在深入了解float之前,相信大家都聽過一個傳說,就是float被設(shè)計出來的目的是為了實現(xiàn)文字環(huán)繞圖片的效果,可能是初學的時候忘了,還是受了“清浮動”的毒,我自己都忘了有沒有用float去實現(xiàn)過這個效果。因此下面我們先來實現(xiàn)一下float的設(shè)計初衷,文字環(huán)繞圖片效果。
<div style="width: 200px">
<div style="float: left;">
<img width="100" height="100" src="../小和尚.jpg">
</div>
<p>我想實現(xiàn)文字環(huán)繞,因此需要多一些文字看一下效果我想實現(xiàn)文字環(huán)繞,因此需要多一些文字看一下效果</p>
</div>

非常簡單的一段代碼,也不需要什么牛逼哄哄的操作,float就幫助我們實現(xiàn)了文字環(huán)繞圖片的效果。為了實現(xiàn)這種效果,CSS設(shè)計師在設(shè)計float屬性的時候定義了float的兩個特性。
(1)“破壞文檔流”,使得父元素得高度塌陷。
(2)禁止行框盒子與浮動元素發(fā)生重疊。
下面我們結(jié)合這兩個特性,來說說圖片是如何環(huán)繞文字的。第一點,破壞文檔流,使得父元素高度塌陷,這個時候,我們的p標簽作為一個block元素,肯定是想著我要填滿父容器的寬度,而事實上,塊級元素也是不辱使命的完成了自己的任務(wù),我們可以給塊級標簽加個背景色,然后把圖片搞成小透明,看一下是不是這樣。

果然,第一個條件生效了,然而高度塌陷只是讓浮動元素和塊級元素在一個水平線上了,如何實現(xiàn)文字環(huán)繞效果呢?這個時候就需要我們的第二個屬性出場了,就是float元素禁止與行框盒子發(fā)生重疊(個人認為這是float和絕對定位的最大區(qū)別之一),對“行框盒子”還不理解的童鞋請轉(zhuǎn)內(nèi)聯(lián)元素那章。注意,我特意強調(diào)了行框盒子,也就是本例中匿名內(nèi)聯(lián)元素生成的每一行,這個跟塊級元素的盒子沒有半毛錢關(guān)系。為了驗證這個想法,我們可以把p標簽轉(zhuǎn)化成內(nèi)聯(lián)元素(display:inline)看下效果。為了看上去更明顯,我把圖片的透明度設(shè)成了0,可以看到,浮動元素確實是和行框盒子發(fā)生了不重疊的關(guān)系。-

至此,我們已經(jīng)完全了解了那個float的傳說。
2.浮動錨點和浮動參考?聽都沒聽過!
我估計在座的各位和我一樣(是個辣雞),都是第一次聽說浮動錨點和浮動參考,更別說去了解特么的概念了。干巴巴的講概念在CSS世界里根本行不通,很多東西都要通過實踐,確認過眼神才能夠去猜測其內(nèi)部的原理。那么我們就通過一個例子來了解一下這兩個概念。
<!-- 測試浮動參考 -->
<div style="width: 200px;text-align: justify;background: yellow">
<span>這里有很多文字,且要超出一行且要超出一行且要超出一行</span>
<span style="float: right;color:blue">更多</span>
</div>
首先上面這個例子,文字超出一行的時候,浮動元素會浮在哪兒?是文字的第一行?還是文字的最后一行?還是隨便???答案是,最后一行,看一下具體效果就知道了。
由于markdown編輯器支持標簽語言,因此我們可以直接預(yù)覽最終效果如下(小提示:你可以通過瀏覽器直接檢查下面的元素看到CSS樣式)

結(jié)果已經(jīng)出來了,那么,為什么呢?
這個時候就要邀請我們的浮動參考出場了。浮動參考,顧名思義,就是指float元素要對齊參考的實體是誰?
在CSS世界中,float元素的浮動參考是“行框盒子”,這個行框盒子特么又出來了,怎么感覺哪兒都有它。注意是行框盒子,跟其父容器子元素等等等等都沒半毛錢關(guān)系。這里作者溫馨提示,在新的標準中,float的浮動參考不僅僅是行框盒子,但他沒有展開,我也懶得查閱,就當留個懸念。知道了浮動參考的概念后,我們就可以解釋上面這個例子了,由于float元素是參考行框盒子對齊的,因此,float可能在第一行,也可能在第二行,為什么在第三行呢?
這里其實作者沒有說明,我提出一個假設(shè),就是浮動元素參考的是離他最近的行框盒子,這個觀點由本人提出,由本人驗證后發(fā)現(xiàn)事實就是這樣,所以有時候CSS的世界就是瞎猜一通然后驗證。下面我來簡單驗證一下這個觀點,其實很簡單,只要把浮動元素放到span標簽前面就可以了。如下所示
<!-- 驗證浮動參考是離他最近的行框盒子 -->
<div style="width: 200px;text-align: justify;background: yellow">
<span style="float: right;color:blue">更多</span>
<span>這里有很多文字,且要超出一行且要超出一行且要超出一行</span>
</div>
由于markdown編輯器支持標簽語言,因此我們可以直接預(yù)覽最終效果如下(小提示:你可以通過瀏覽器直接檢查下面的元素看到CSS樣式)

結(jié)果完全印證了我的想法是正確的,我吹爆我自己!
說完了浮動參考,那么什么是浮動錨點?浮動錨點是float元素所在流中的一個點,你可以理解為是一個空的內(nèi)聯(lián)元素,為什么要有這個點呢?道理很簡單,有時候我們的浮動元素沒有可以參考的行框盒子,也就是他的四周都被一群block大漢包圍的時候該怎么辦?往哪里定位?沒有關(guān)系,他自己帶一個可以參考的浮動錨點。由于這個屬性沒什么特殊之處,這里就不過多介紹了,了解一下就好。
3.那些年你被騙過的clear“清浮動”
相信我們初學浮動的第一課便被灌輸了“浮動”破壞文檔流是個禍害的思想,為了解決浮動元素導(dǎo)致高度坍塌的“bug”,我們被要求清浮動。然后給了一大堆清浮動的方法,最后提出最好用的是after偽類清浮動,當時還真覺得煞有其是,現(xiàn)在看來真的是人言可畏。如果CSS自家制定的標準都被當作了bug,那還有什么不是bug呢?
看完這一章后,你應(yīng)該可以明白兩個概念:第一,浮動引起的高度坍塌是為了解決圖文環(huán)繞效果而被制定的標準,并不是所謂的bug。第二,所謂的clear清浮動,并沒有清除掉浮動。
為什么說clear沒有清除掉浮動呢?從字面意思上理解,clear確實是清除的意思,然而官方對于clear的解釋是:元素盒子的邊不能和前面的浮動元素相鄰。
這句話聽起來很拗口,但可以明確的知道,clear并沒有改變?nèi)魏胃釉氐奶匦?,浮動元素依舊是那個浮動元素,不管你清不清,他還是在那邊,浮著。
那么這句話的涵義是什么呢?仔細剖析一下,你會發(fā)現(xiàn),“清浮動”的奧秘就在于這個不能相鄰的標準。事實上,clear被制定出來就是為了解決口耳相傳的“高度坍塌bug”,因此浮動元素本身的特性被完美保留。概念講的干了,來看一個例子吧
<!-- 清浮動原理探究 -->
<div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
</div>
<style>
.li{
float: left;
margin: 10px;
width: 40px;
height: 40px;
background: yellow
}
.li:nth-of-type(3){
clear: both;
}
</style>
上面這個例子,最終li會被清浮動分割成幾行?
最終結(jié)果是:兩行。由于markdown編輯器支持標簽語言,因此我們可以直接預(yù)覽最終效果如下(小提示:你可以通過瀏覽器直接檢查下面的元素看到CSS樣式)

我們用所學的理論知識來解釋下為什么是兩行,在樣式表中,第三個浮動元素使用了清浮動的屬性,此時,根據(jù)標準,當前元素不能和前面的浮動元素相鄰,也就是第三個元素不能和第二個元素做朋友了,那只能換行了,然而標準沒有規(guī)定第三個元素不能和后面的元素做朋友,因此第三個元素以及之后的元素依舊保持左浮動的特性規(guī)則排列。由于第一行和第二行都保持了浮動的特性,因此高度全部坍塌,此時父級容器div的高度依舊是0,不會因為清了浮動,父容器的高度就變成第一行的高度了,父容器高度依舊是0!注意是0!(由于我直接用了標簽去展示結(jié)果,父元素高度坍塌會導(dǎo)致文章排版出問題,因此F12檢查元素的時候會發(fā)現(xiàn)父元素高度不是0,是因為利用了BFC特性加了overflow,這個在下一章會詳細探討)
看完了上面的例子,再來簡單了解下clear的四個屬性,分別是none(默認,就是沒有),left(清左浮動),right(清右浮動)以及我們最常用的both(全清)。作者這里給出了clear的基本使用方式就是clear:both。left和right屬性根本沒有軟用,讓CSS自己判斷就好了,因為不可能有一個元素既是left又是right浮動的,因此無需考慮是清左浮動還是右浮動,全清就完事了。
由于clear只能確保和前面的元素發(fā)生關(guān)系,因此我們最常使用的是after偽類清浮動,而不是before,因為before生成的元素根本沒法和后面的元素交流clear的事情。最后我們放上我們最喜歡使用的after偽類清浮動的方法,注意clear屬性只有塊級元素才有效,而偽類的默認屬性是內(nèi)聯(lián)值,不要忘了display:block申明。
<div class="clearfix">
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
<div class="li"></div>
</div>
<style>
.li{
float: left;
margin: 10px;
width: 40px;
height: 40px;
background: yellow
}
.li:nth-of-type(3){
clear: both;
}
.clearfix::after{
content: '';
display: block;
clear: both;
}
</style>
復(fù)制代碼

本章到這里其實還沒有結(jié)束,下一章的內(nèi)容會繼續(xù)探討float的BFC特性,以及如何用overflow真正的清除浮動。
最后,給大家推薦一個前端學習進階內(nèi)推交流群685910553(前端資料分享),不管你在地球哪個方位,
不管你參加工作幾年都歡迎你的入駐?。ㄈ簝?nèi)會定期免費提供一些群主收藏的免費學習書籍資料以及整理好的面試題和答案文檔?。?/p>
如果您對這個文章有任何異議,那么請在文章評論處寫上你的評論。
如果您覺得這個文章有意思,那么請分享并轉(zhuǎn)發(fā),或者也可以關(guān)注一下表示您對我們文章的認可與鼓勵。
愿大家都能在編程這條路,越走越遠。