我們在日常開發(fā)布局中經(jīng)常會使用到流體布局,流體布局用到的一個最重要的屬性就是浮動,今天就來看看浮動的相關(guān)知識。
1).什么是浮動?
float即為浮動,在CSS中的作用是使元素脫離正常的文檔流并使其移動到其父元素的“最左邊”或“最右邊”。
文檔流:在html中文檔流即為元素從上至下排列的順序。
脫離文檔流:元素從正常的排列順序被抽離。
最左邊/最右邊:上述的移動到父元素最左和最右是指元素往左或往右移動直到碰到另一個浮動元素或父元素內(nèi)容區(qū)的邊界(不包括padding)。
2).為何要清除浮動?
要解答這個問題,我們得先說說CSS中的定位機制:普通流,浮動。
a.普通流:很多人或者文章稱之為文檔流或者普通文檔流,其實標(biāo)準(zhǔn)里根本就沒有這個詞。如果把文檔流直譯為英文就是 document flow ,但標(biāo)準(zhǔn)里只有另一個詞,叫做 普通流(normal flow),或者稱之為常規(guī)流。但似乎大家更習(xí)慣文檔流的稱呼,因為很多中文翻譯的書就是這么來的。比如《CSS Mastery》,英文原書中至始至終都只有普通流 normal flow(普通流) 這一詞,從來沒出現(xiàn)過document flow(文檔流).
b.浮動:浮動的框可以左右移動,直至它的外邊緣遇到包含框或者另一個浮動框的邊緣。浮動框不屬于文檔中的普通流,當(dāng)一個元素浮動之后,不會影響到 塊級框的布局而只會影響內(nèi)聯(lián)框(通常是文本)的排列,文檔中的普通流就會表現(xiàn)得和浮動框不存在一樣,當(dāng)浮動框高度超出包含框的時候,也就會出現(xiàn)包含框不會 自動伸高來閉合浮動元素(“高度塌陷”現(xiàn)象)。顧名思義,就是漂浮于普通流之上,像浮云一樣,但是只能左右浮動。
正是因為浮動的這種特性,導(dǎo)致本屬于普通流中的元素浮動之后,包含框內(nèi)部由于不存在其他普通流元素了,也就表現(xiàn)出高度為0(高度塌陷)。在實際布局中,往往這并不是我們所希望的,所以需要閉合浮動元素,使其包含框表現(xiàn)出正常的高度。
清除浮動 還是 閉合浮動 (Enclosing float or Clearing float)?
很多人都已經(jīng)習(xí)慣稱之為清除浮動,但是確切地來說是不準(zhǔn)確的。
1)清除浮動:清除對應(yīng)的單詞是 clear,對應(yīng)CSS中的屬性是 clear:left | right | both | none;
2)閉合浮動:更確切的含義是使浮動元素閉合,從而減少浮動帶來的影響。
其實我們想要達(dá)到的效果更確切地說是閉合浮動,而不是單純的清除浮動,在footer上設(shè)置clear:both清除浮動并不能解決wrap高度塌陷的問題。
有哪些清除浮動的方法?
1)父級div定義 height
原理:父級div手動定義height,就解決了父級div無法自動獲取到高度的問題。
優(yōu)點:簡單、代碼少、容易掌握
缺點:只適合高度固定的布局,要給出精確的高度,如果高度和父級div不一樣時,會產(chǎn)生問題
建議:不推薦使用,只建議高度固定的布局時使用
2)添加額外標(biāo)簽
原理:添加一個空div,通過在浮動元素末尾添加一個空的標(biāo)簽例如 div style="clear:both" ,其他標(biāo)簽br等亦可,讓父級div能自動獲取到高度
優(yōu)點:通俗易懂,容易掌握
缺點:可以想象通過此方法,會添加多少無意義的空標(biāo)簽,有違結(jié)構(gòu)與表現(xiàn)的分離,在后期維護中將是噩夢,這是堅決不能忍受的,所以你看了這篇文章之后還是建議不要用了吧
建議:不推薦使用,但此方法是以前主要使用的一種清除浮動方法。
3)父元素設(shè)置 overflow:hidden
原理:必須定義width,在IE6中還需要觸發(fā) hasLayout ,例如 zoom:1,同時不能定義height,使用overflow:hidden時,瀏覽器會自動檢查浮動區(qū)域的高度
優(yōu)點:不存在結(jié)構(gòu)和語義化問題,代碼量極少
缺點:內(nèi)容增多時候容易造成不會自動換行導(dǎo)致內(nèi)容被隱藏掉,不能和position配合使用,無法顯示需要溢出的元素;04年P(guān)OPO就發(fā)現(xiàn)overflow:hidden會導(dǎo)致IE中中鍵失效,按鼠標(biāo)中鍵時,那個上下滾屏箭頭不會出現(xiàn)
建議:只推薦沒有使用position或?qū)verflow:hidden理解比較深的朋友使用。
4)使用:after 偽元素
原理:IE8以上和非IE瀏覽器才支持:after,原理和方法2有點類似,由于IE6-7不支持:after,使用 zoom:1觸發(fā) hasLayout。需要注意的是 :after是偽元素,不是偽類
.clearfix:after {content:" "; display:block; height:0; visibility:hidden; clear:both; }
.clearfix { *zoom:1; }
優(yōu)點:結(jié)構(gòu)和語義化完全正確,代碼量居中。瀏覽器支持好、不容易出現(xiàn)怪問題(bootstrap用的也是這種方法)
缺點:復(fù)用方式不當(dāng)會造成代碼量增加,初學(xué)者不理解原理,要兩句代碼結(jié)合使用才能讓主流瀏覽器都支持。
建議:推薦使用,建議定義公共類,以減少CSS代碼。
5)父元素設(shè)置 overflow:auto 屬性
原理:必須定義width或zoom:1,同時不能定義height,使用overflow:auto時,瀏覽器會自動檢查浮動區(qū)域的高度
優(yōu)點:不存在結(jié)構(gòu)和語義化問題,代碼量極少
缺點:多個嵌套后,firefox某些情況會造成內(nèi)容全選;IE中 mouseover 造成寬度改變時會出現(xiàn)最外層模塊有滾動條等,firefox早期版本會無故產(chǎn)生focus等
建議:不推薦使用,如果你需要出現(xiàn)滾動條或者確保你的代碼不會出現(xiàn)滾動條就使用吧。
6)父元素也設(shè)置浮動
原理:所有代碼一起浮動,就變成了一個整體
優(yōu)點:不存在結(jié)構(gòu)和語義化問題,代碼量極少
缺點:使得與父元素相鄰的元素的布局會受到影響,不可能一直浮動到body
建議:不推薦使用,只作了解。
7)父元素設(shè)置display:table
原理:將div屬性變成表格
優(yōu)點:結(jié)構(gòu)語義化完全正確,代碼量極少
缺點:盒模型屬性已經(jīng)改變,由此造成的一系列問題,得不償失
建議:不推薦使用,只作了解
小結(jié)
通過對比,我們不難發(fā)現(xiàn),其實以上列舉的方法,無非有兩類:
其一,通過在浮動元素的末尾添加一個空元素,設(shè)置 clear:both屬性,after偽元素其實也是通過 content 在元素的后面生成了內(nèi)容為一個空格的table元素;
其二,通過設(shè)置父元素 overflow 或者display:table 屬性來閉合浮動,我們來探討一下這里面的原理。
在CSS2.1里面有一個很重要的概念,但是國內(nèi)的技術(shù)博客介紹到的比較少,那就是 Block formatting contexts (塊級格式化上下文),以下簡稱 BFC。
CSS3里面對這個規(guī)范做了改動,稱之為:flow root,并且對觸發(fā)條件進行了進一步說明。
那么如何觸發(fā)BFC呢?
float 除了none以外的值
overflow 除了visible 以外的值(hidden,auto,scroll )
display (table-cell,table-caption,inline-block)
position(absolute,fixed)
fieldset元素
BFC的特性:
1)塊級格式化上下文會阻止外邊距疊加
當(dāng)兩個相鄰的塊框在同一個塊級格式化上下文中時,它們之間垂直方向的外邊距會發(fā)生疊加。換句話說,如果這兩個相鄰的塊框不屬于同一個塊級格式化上下文,那么它們的外邊距就不會疊加。
2)塊級格式化上下文不會重疊浮動元素
根據(jù)規(guī)定,一個塊級格式化上下文的邊框不能和它里面的元素的外邊距重疊。這就意味著瀏覽器將會給塊級格式化上下文創(chuàng)建隱式的外邊距來阻止它和浮動元素的外邊距疊加。
由于這個原因,當(dāng)給一個挨著浮動的塊級格式化上下文添加負(fù)的外邊距時將會不起作用
如何使一個浮動元素垂直居中?
給父元素設(shè)置display: table-cell 和vertical-middle 即可。