習慣性去谷歌翻譯看了看float的解釋: css
she relaxed, floating gently in the waterhtml
瞬間浮想聯翩,一個女神,輕輕地漂浮在水中。開心的拍打着水花,哇靠。。。前端
不想了,人間不值得,步入正題吧,上面美妙的畫面中,咱們能夠看到,女神仍是擠佔了水的空間,女神是浮動的。那麼來,好了,編不下去了,直接開題吧。。。api
我以爲不少人連float
是啥意識都不知道,要知道不少特性的原理是和其命名的單詞或者字母有密切關聯的,不是隨便命名的。從名字中能夠看到一些當初設計的初衷。瀏覽器
問本身三個問題:bash
第一 浮動會形成什麼影響?
第二,如何解決這些由於浮動而形成的影響?
第三,bfc原理?
複製代碼
其實我我的理解,浮動形成的最核心的問題就是破壞了文檔流,那麼問題來了,float
破壞了文檔流,爲何還要設計這個api
,我查了一些資料最後才知道,這是由於當初設計float
的目的是爲了能實現文字可以環繞圖片的排版功能,也就是咱們有時會納悶的一點:設置浮動後,仍是會擠佔容器中的文本內容。佈局
好比看下面這段代碼:spa
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>float實現浮動</title>
</head>
<style> .z1{ height: 200px; width: 200px; float: left; text-align: center; line-height: 200px; background: skyblue; } .fu { width: 400px; } </style>
<body>
<div class="fu clearfix">
<div class="z1">設置了float爲left的圖片</div>
<div class="z2">你看,我沒有被浮動哥哥擋住哦,這是一段神奇旅行,一天我趕上了白雪公主</div>
</div>
</body>
</html>
複製代碼
效果圖以下:翻譯
看到這,是否是有些理解了。從上圖會發現,即便圖片浮動了,脫離了正常文檔流,也覆蓋在沒有浮動的元素上了,可是其並無將文本內容也覆蓋掉,這也證明了float
這個api
在當初被設計出來的主要目的:實現文字環繞圖片排版功能。設計
當想到這時,我忽然意識到,其餘佈局模式是什麼樣子,而後進行了實驗。去掉容器z1
的float
屬性,增長了position
屬性,代碼以下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>absolute實現浮動</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; position: absolute; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.8; } .fu { width: 400px; } </style>
<body>
<div class="fu clearfix">
<div class="z1">設置了positon爲absolute的圖片</div>
<div class="z2">你看,我被absolute哥哥擋住哦,這是一段神奇旅行,一天我趕上了白雪公主</div>
</div>
</body>
</html>
複製代碼
效果圖以下:
咱們能夠看到,設置absolute
的容器,纔是意義上的徹底脫離正常文檔流。覆蓋在當前位置上的全部容器和文本內容之上。對比思考一下,會發現這又證實了float
被設計出來的主要目的。若是能理解成這樣,我以爲對於不一樣業務上該用什麼方式清除float
,或者說該用什麼來代替float
,將會有個很明確的方向。
其實你會發現,absolute
和float
都不會去覆蓋掉在他們以前的正常文檔流,這應該和瀏覽器渲染機制有關係,會從上到下依次渲染內容,渲染成功後,就不會由於後續元素浮動而使其被覆蓋住(不考慮使用fix等強行覆蓋的狀況)。
簡易代碼以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮動</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; } .z5 { background: pink; } </style>
<body>
<div class="fu">
<div class="z2">沒有設置任何浮動的容器,背景爲黃色</div>
<div class="z3">沒有設置任何浮動的容器,背景爲紅色</div>
<div class="z1">設置了浮動的元素,opacity爲0.5</div>
<div class="z4">沒有設置任何浮動的容器,背景爲綠色</div>
<div class="z5">沒有設置任何浮動的容器,背景爲粉色</div>
</div>
</body>
</html>
複製代碼
效果圖以下:
從圖中的標註和說明咱們能夠清晰的知道,float
不會影響前面已經渲染好的文檔,而會影響在其後面將要渲染的文檔。那麼問題來了,怎樣才能消除由於z1
的浮動而對z4
,z5
形成的影響呢?
首先咱們要知道,z1
這個浮動形成了哪些影響,影響以下:
第一個影響:影響了
z4
,z5
的佈局。
第二個影響:影響了父容器的高度,正常父元素的高度是自適應的,高度爲其包含的內容總高度,而內部元素的浮動形成了父容器高度塌陷。
第三個影響:父容器高度塌陷了,將會影響和父元素同級的文檔佈局。
下面的代碼能夠完美的詮釋這些影響:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮動</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; } .z5 { background: pink; } .z6 { color: #fff; background: black; } .z7 { color: #fff; background: blue; } .fu { /* overflow: hidden; */ } </style>
<body>
<div class="fu">
<div class="z2">沒有設置任何浮動的容器, 背景爲黃色</div>
<div class="z3">沒有設置任何浮動的容器, 背景爲紅色</div>
<div class="z1">設置了浮動的元素, opacity爲0.5</div>
<div class="z4">沒有設置任何浮動的容器, 背景爲綠色</div>
<div class="z5">沒有設置任何浮動的容器, 背景爲粉色</div>
</div>
<div class="z6">和父級元素同級的容器, 沒有設置任何浮動, 背景爲綠色</div>
<div class="z7">和父級元素同級的容器, 沒有設置任何浮動, 背景爲綠色</div>
</body>
</html>
複製代碼
效果圖以下:
要解決這三個影響,須要從兩個方向思考:
第一個方向:解決父元素給其同級的元素形成的影響,我比喻成解決外部矛盾。
第二個方向:解決父級元素內部的浮動元素對其同級元素的影響,我比喻成解決內部矛盾。
俗話說的好,家醜不可外揚,那麼來,如今就先解決外部矛盾,怎麼解決呢,解決的思想,無非就是讓父級元素的高度再也不塌陷,把浮動元素的高度算進去。記住一個關鍵點,這時候,內部矛盾仍是存在的。好比浮動元素和其後續的同級元素有高度重疊。
第一個是觸發bfc
,爲何呢,由於觸發bfc
後,高度會包括浮動元素的高度。怎麼觸發呢,能夠給父級元素設置overflow:auto;
對於其餘的觸發bfc
方式,我就不說了,我主要說一下原理。代碼以下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮動</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; } .z5 { background: pink; } .z6 { color: #fff; background: black; } .z7 { color: #fff; background: blue; } .fu { overflow: hidden; } </style>
<body>
<div class="fu">
<div class="z2">沒有設置任何浮動的容器, 背景爲黃色</div>
<div class="z3">沒有設置任何浮動的容器, 背景爲紅色</div>
<div class="z1">設置了浮動的元素, opacity爲0.5</div>
<div class="z4">沒有設置任何浮動的容器, 背景爲綠色</div>
<div class="z5">沒有設置任何浮動的容器, 背景爲粉色</div>
</div>
<div class="z6">和父級元素同級的容器, 沒有設置任何浮動, 背景爲綠色</div>
<div class="z7">和父級元素同級的容器, 沒有設置任何浮動, 背景爲綠色</div>
</body>
</html>
複製代碼
效果圖以下:
給父元素增長僞元素:代碼以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮動</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; /* clear: left */ } .z5 { background: pink; } .z6 { color: #fff; background: black; } .z7 { color: #fff; background: blue; } .fu { } .clearfix:after { display: block; overflow: hidden; content: '僞元素的內容哦'; clear: both; height: 0; background: slateblue; } </style>
<body>
<div class="fu clearfix">
<div class="z2">沒有設置任何浮動的容器, 背景爲黃色</div>
<div class="z3">沒有設置任何浮動的容器, 背景爲紅色</div>
<div class="z1">設置了浮動的元素, opacity爲0.5</div>
<div class="z4">沒有設置任何浮動的容器, 背景爲綠色</div>
<div class="z5">沒有設置任何浮動的容器, 背景爲粉色</div>
</div>
<div class="z6">和父級元素同級的容器, 沒有設置任何浮動, 背景爲綠色</div>
<div class="z7">和父級元素同級的容器, 沒有設置任何浮動, 背景爲綠色</div>
</body>
</html>
複製代碼
不少人不清楚用僞元素清除浮動的原理是什麼,爲何給父元素加這個僞元素,能夠清除父元素的浮動。這裏我故意在僞元素的content
寫了一些文本內容,同時加了背景色,有點像基佬色。。。
OK,先看總體效果圖吧:
display:block
,繼續看下一個截圖。
height
要設置成0了。若是
content
不是空字符串,那麼就會在頁面中顯示內容。但其實清除浮動時,
content
都會寫成空的字符串,若是
content
裏面只設置成
''
空的字符,那麼
height
也能夠不寫,包括
overflow
也能夠不寫,寫
height
和
overflow
都是爲了代碼的魯棒性。不過有個很重要,
content
這個屬性,必需要寫,不寫
content
,是無法清除浮動的。
最重要的知識點要來了,請看兩個截圖:
content
顯示出來,會發現
僞元素清除浮動的核心原理實際上是在給父元素增長塊級容器,同時對塊級容器設置clear
屬性,使其可以清除自身的浮動,從而正常按照塊級容器排列方式那樣排列在浮動元素的下面。同時,父元素的同級元素也會正常排列在僞元素造成的塊級元素後面,而不受浮動影響。
下面是幹掉clear
屬性後的截圖:
給父元素再加一個塊級子容器,固然這個也就是父元素的最後一個塊級子容器了。同時給這個塊級子容器設置clear屬性來清除其浮動,這樣這個子容器就能排列在浮動元素的後面,同時也把父元素的高度撐起來了。那麼父元素的同級元素也能正常排列了。因此這個子容器不能有高度和內容,否則會影響父元素的佈局。
寫到這,外部矛盾的解決方式和各自的原理已經說的很清楚了。那麼內部矛盾怎麼解決呢?
其實,解決內部矛盾的原理和解決外部矛盾的第二種方式的原理是同樣的,經過給被浮動影響的第一個元素進行清除浮動,就可使後面的元素也不會受到浮動影響了。代碼以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮動</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; clear:both; } .z5 { background: pink; } .z6 { color: #fff; background: black; } .z7 { color: #fff; background: blue; } </style>
<body>
<div class="fu">
<div class="z2">沒有設置任何浮動的容器, 背景爲黃色</div>
<div class="z3">沒有設置任何浮動的容器, 背景爲紅色</div>
<div class="z1">設置了浮動的元素, opacity爲0.5</div>
<div class="z4">沒有設置任何浮動的容器, 背景爲綠色</div>
<div class="z5">沒有設置任何浮動的容器, 背景爲粉色</div>
</div>
<div class="z6">和父級元素同級的容器, 沒有設置任何浮動, 背景爲綠色</div>
<div class="z7">和父級元素同級的容器, 沒有設置任何浮動, 背景爲綠色</div>
</body>
</html>
複製代碼
效果圖以下:
給內部元素設置clear:both;
清除浮動後,會直接解決內部矛盾和外部矛盾。可能會有人想,若是z4容器後面又有一個浮動元素呢,這裏我不想再解釋了,由於可遞歸得出原理都是同樣的,可是吧,我仍是上個代碼分析一下吧:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮動</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; clear:both; } .z5 { background: pink; /* clear:both */ } .z6 { color: #fff; background: black; } .z7 { color: #fff; background: blue; } .fu { overflow: auto; } </style>
<body>
<div class="fu">
<div class="z2">沒有設置任何浮動的容器, 背景爲黃色</div>
<div class="z3">沒有設置任何浮動的容器, 背景爲紅色</div>
<div class="z1">設置了浮動的元素, opacity爲0.5</div>
<div class="z4">沒有設置任何浮動的容器, 背景爲綠色</div>
<div class="z1">設置了浮動的元素, opacity爲0.5</div>
<div class="z5">沒有設置任何浮動的容器, 背景爲粉色</div>
</div>
<div class="z6">和父級元素同級的容器, 沒有設置任何浮動, 背景爲綠色</div>
<div class="z7">和父級元素同級的容器, 沒有設置任何浮動, 背景爲綠色</div>
</body>
</html>
複製代碼
效果圖以下幾張截圖:
父元素沒有清除浮動,外部矛盾,內部矛盾都存在
父元素使用bfc清除浮動,外部矛盾解決,內部矛盾還存在
經過給父元素中的浮動元素後面的第一個同級塊級元素設置clear清除浮動,內部矛盾解決,外部矛盾也解決。
對於clear
還有left
和right
,這個就不說了,api
的事情,正常both
就能夠了。寫到此,差很少要結束了。最後再總結一下吧:
不一樣業務中可能須要不一樣的清除浮動的方式,不論選擇哪種方式,都避不開外部矛盾和內部矛盾,你的業務須要保留內部矛盾,只解決外部矛盾,仍是外部矛盾和內部矛盾都解決。這些得須要根據業務的特色來決定。其次,是使用bfc仍是clear仍是僞元素,使用bfc的話使用哪一種方式去觸發。這也是根據業務的特色來決定。
文末的可愛聲明:若是轉發或者引用,請貼上原連接,尊重一下熬夜完成的勞動成果😂。文章可能有一些錯誤,歡迎評論指出,也歡迎一塊兒討論。文章可能寫的不夠好,還請多多包涵。爲了前端,我也是操碎了心,人生苦短,我學前端,多一點貢獻,多一分開心~