前言
最近在準備春招面試,好幾個前端朋友面試的時候被問到了浮動與浮動清除的問題。雖然平時經常用到浮動,但對浮動隻是一知半解,不清楚原理到底是怎樣的。不知道各位有沒有跟我一樣的感覺,是以我找了一段整塊時間研究了一下浮動的原理和清除浮動的方法,并寫下這篇分享文章。此分享僅供參考,有什麼了解錯誤的地方敬請大家指正。
CSS常用的三種布局方式
在CSS中元素分三類:行内元素(inline)、塊級元素(block)和行内塊級元素(inline-block),在不同的布局方式下,元素會表現出不同的行為。
文檔流(标準流)
這是浏覽器預設的布局方式,在這種布局下,行内元素和行内塊級元素水準布局,塊級元素垂直布局。
浮動流
半脫離标準流的布局方式,隻有水準排版方式,隻能設定元素左對齊或者右對齊,沒有居中對齊。浮動流中不區分元素類型,無論哪種元素都可以水準排版,與标準流中的行内塊級元素很像。
定位流
其中static是預設方式,也就是标準流,relative不脫離标準流,以其原本在标準流中的位置相對定位,會在标準流中占位(效果可以大緻了解為設定了margin),absolute和fixed完全脫離标準流,對标準流沒有任何影響。
三種布局方式的層級關系:浮動流高于标準流,定位流高于浮動流。這句話現在不了解沒關系,後面我們會具體看到。
浮動
下面我們具體看一下浮動布局。在我們預設的标準流中,每個塊級元素占一行,自上而下排列。
我如果希望在一行中顯示多個div,顯然标準流是做不到的,這個時候我們就需要用到浮動,讓這個div脫離标準流,顧名思義就是飄浮在标準流上面。我給div1加一個float:left;看看會發生什麼。
我們發現綠色的div2不見了,其實div2并沒有消失,而是“鑽”到div1下面去了。因為給div1加左浮動之後,div1脫離标準流飄起來,而div2依然在标準流中,這時div2發現标準流中他的前面沒有其他元素了,是以他就“鑽”到了div1的下面,也就是div1原本在标準流中的位置。
現在我們再回過頭看前面我們說到的,浮動流是半脫離标準流的布局方式,并且浮動流的層級高于标準流。為什麼說是半脫離标準流呢?這是因為浮動元素不能改變其自身和上面的标準流元素的垂直位置關系。那麼為什麼又說浮動流的層級比标準流高呢?因為浮動流元素下面的标準流元素會“鑽”到他的下方。
浮動清除
浮動有時候會給我們的布局帶來很多便利,但同時,我們也必須面對和處理浮動帶來的影響。首先,我們來看浮動會帶來什麼問題,現在有三個div,屬于标準流,各占一行。如圖:
現在我希望前兩個div在同一行而div3的位置在div1和div2的下面,這個時候就用到浮動了,給前兩個div添加一個浮動,結果并不是我們想要的,如圖:
原因就是上面所說的,前兩個浮動的div脫離了标準流,而浮動流的層級高于标準流,是以就相當于前兩個div飄起來了,是以屬于标準流的div3發現标準流上面沒有元素了,它自然會頂上去。但這并不是我們希望要的效果,是以現在就要用到浮動清除。這裡先說第一個方法,隔牆法。
顧名思義,隔牆法就是在需要清除浮動的元素和浮動元素之間添加一個空的塊級元素,并給他一個clear屬性,或者給div3一個clear屬性,其中clear屬性可以是如下這幾個值:both/left/right/none/inherit,分别表示左右兩邊均不允許出現浮動元素、左邊不允許出現浮動元素、右邊不允許出現浮動元素、不清除浮動、繼承父元素的值。直接上代碼(第一種,這是W3C推薦的方法):
<body>
<div id="div1">div1</div>
<div id="div2">div2</div>
<div class="clear"></div>
<div id="div3">div3</div>
</body>
<style>
.clear{
clear:both;
}
</style>
在div1.2和div3中間空的div起到像一面牆把浮動元素和不浮動的元素隔開,我們看一下效果圖:
那麼clear是怎麼做到這一點的呢?clear 會為元素添加空白空間(可以了解為外邊距),使得該元素會被放置在它前一個浮動元素之下,這跟增加元素外邊距使得元素占據滿行而強制換行是一個道理。
了解了clear之後,我們再來看看浮動會帶來的第二種問題,現在有如下結構和樣式的頁面:
<body>
<div id=”div3”>
<div id="div1">div1</div>
<div id="div2">div2</div>
</div>
</body>
<style>
#div1{
background: red;
height: 100px;
width: 100px;
color: #000;
font-size: 20px;
}
#div2{
background: greenyellow;
height: 100px;
width: 100px;
color: #000;
font-size: 20px;
}
#div3{
background: lightblue;
}
</style>
看一下效果,很容易了解div1和div2把父元素撐開了,如圖:
這時,一個鬼魅的操作湧上心頭,我想讓div1和div2放在一行,是以現在我給div1和div2加一個浮動,來看看會有什麼變化:
背景去哪了?原來是因為div1和div2加了浮動脫離了标準流,原本撐開父元素的标準流裡的div1和div2飄起來了,沒有元素來把父元素撐開,是以父元素就“消失”了,這就是常說的“高度塌陷”,但我們不想讓高度塌陷,是以這個時候就要清除浮動了。現在給出清除浮動的第二種方法,在父元素上設定overflow屬性為auto或者hidden,這樣一來父元素就會擴充包含浮動(根本原因是因為父元素變成BFC,能包含浮動元素)。現在我們給父元素加上overflow屬性:
<body>
<div id"div3">
<div id="div1">div1</div>
<div id="div2">div2</div>
</div>
</body>
<style>
#div1{
background: red;
height: 100px;
width: 100px;
color: #000;
font-size: 20px;
}
#div2{
background: greenyellow;
height: 100px;
width: 100px;
color: #000;
font-size: 20px;
}
#div3{
background: lightblue;
overflow:hidden;
}
</style>
來看看效果:
現在外面的父元素就又出現了,需要注意的是,overflow原本不是用來清除浮動的,有可能會導緻即使高度沒有超出限制,但還是出現滾動條的情況。
還有一種方法就是使用:after僞元素,話不多說直接上代碼。
<body>
<div id="div3">
<div id="div1">div1</div>
<div id="div2">div2</div>
</div>
</body>
<style>
#div1{
background: red;
height: 100px;
width: 100px;
color: #000;
font-size: 20px;
}
#div2{
background: greenyellow;
height: 100px;
width: 100px;
color: #000;
font-size: 20px;
}
#div3{
background: lightblue;
}
.clear:after {
content: "";
display: block;
height: 0;
clear: both;
}
</style>
可以看到這種方法把清除浮動寫成公共樣式,隻要在需要清除浮動的地方添加這個類就可以,最終效果跟上面是一樣的。相對來說這種方法最友善,重用性好,相容主流浏覽器,最推薦使用。
參考文獻
https://www.cnblogs.com/zhongweizhu/p/6003537.html
以上是我對浮動與清除浮動的了解,如有錯誤還請大牛指正,如有不同意見也歡迎質疑,希望對大家有所幫助,也希望同樣在準備春招的朋友一切順利。