CSS好文推薦

 
那些年咱們一塊兒清除過的浮動:做者將CSS清除浮動的原理、清楚浮動的相關方法及其優缺點都進行了詳細的描述和分析!強烈推薦。

 浮動(float),一個咱們即愛又恨的屬性。愛,由於經過浮動,咱們能很方便地佈局;
恨,浮動以後遺留下來太多的問題須要解決,特別是IE6-7(如下無特殊說明均指 windows 平臺的
IE瀏覽器)。也許不少人都有這樣的疑問,浮動從何而來?咱們爲什麼要清除浮動?清除浮動的原理是什麼?本文將一步一步地深刻剖析其中的奧祕,讓浮動使用起來更加駕輕就熟。pWW上海雲路網絡科技有限公司php


1、清除浮動 仍是 閉合浮動 (Enclosing float or Clearing float)?


不少人都已經習慣稱之爲清除浮動,之前我也一直這麼叫着,可是確切地來講是不許確的。咱們應該用嚴謹的態度來對待代碼,也能更好地幫助咱們理解開頭的三個問題。pWW上海雲路網絡科技有限公司css


1)清除浮動:清除對應的單詞是 clear,對應CSS中的屬性是 clear:left | right | both | none;pWW上海雲路網絡科技有限公司html


2)閉合浮動:更確切的含義是使浮動元素閉合,從而減小浮動帶來的影響。pWW上海雲路網絡科技有限公司html5


二者的區別 請看優雅的
Dem
o
pWW上海雲路網絡科技有限公司css3


經過以上實例發現,其實咱們想要達到的效果更確切地說是閉合浮動,而不是單純的清除浮動,在footer上設置clear:both清除浮動並不能解決warp高度塌陷的問題。
 pWW上海雲路網絡科技有限公司chrome


結論:用閉合浮動比清除浮動更加嚴謹,因此後文中統一稱之爲:閉合浮動。pWW上海雲路網絡科技有限公司windows


2、爲什麼要清除浮動?


要解答這個問題,咱們得先說說CSS中的定位機制:普通流,浮動,絕對定位 (其中"position:fixed" 是 "position:absolute"
的一個子類)。pWW上海雲路網絡科技有限公司瀏覽器


1)普通流:不少人或者文章稱之爲文檔流或者普通文檔流,其實標準里根本就沒有這個詞。若是把文檔流直譯爲英文就是 document flow
,但標準裏只有另外一個詞,叫作 普通流 (normal
flow),或者稱之爲常規流。但彷佛你們更習慣文檔流的稱呼,由於不少中文翻譯的書就是這麼來的。好比《CSS Mastery》,英文原書中至始至終都只有普通流
normal flow(普通流) 這一詞,歷來沒出現過document flow (文檔流)pWW上海雲路網絡科技有限公司網絡


2)浮動:浮動的框能夠左右移動,直至它的外邊緣遇到包含框或者另外一個浮動框的邊緣。浮動框不屬於文檔中的普通流,當一個元素浮動以後,不會影響到塊級框的佈局而只會影響內聯框(一般是文本)的排列,文檔中的普通流就會表現得和浮動框不存在同樣,當浮動框高度超出包含框的時候,也就會出現包含框不會自動伸高來閉合浮動元素(「高度塌陷」現象)。顧名思義,就是漂浮於普通流之上,像浮雲同樣,可是隻能左右浮動。pWW上海雲路網絡科技有限公司ide


正是由於浮動的這種特性,致使本屬於普通流中的元素浮動以後,包含框內部因爲不存在其餘普通流元素了,也就表現出高度爲0(高度塌陷)。在實際佈局中,每每這並非咱們所但願的,因此須要閉合浮動元素,使其包含框表現出正常的高度。pWW上海雲路網絡科技有限公司


絕對定位就很少說了,不在本文討論範圍以內,下回分解。pWW上海雲路網絡科技有限公司


3、清除浮動的原理——瞭解 hasLayout 和 Block formatting contexts


先看一下清理浮動的各類方法:pWW上海雲路網絡科技有限公司


1)添加額外標籤pWW上海雲路網絡科技有限公司


這是在學校老師就告訴咱們的 一種方法,經過在浮動元素末尾添加一個空的標籤例如 <div
style=」clear:both」></div>,其餘標籤br等亦可。pWW上海雲路網絡科技有限公司



 <div class="warp"
id="float1">
pWW上海雲路網絡科技有限公司


<h2>1)添加額外標籤</h2>pWW上海雲路網絡科技有限公司


<div class="main
left">.main{float:left;}</div>
pWW上海雲路網絡科技有限公司


<div class="side
left">.side{float:right;}</div>
pWW上海雲路網絡科技有限公司


<div
style="clear:both;"></div>
pWW上海雲路網絡科技有限公司


</div>pWW上海雲路網絡科技有限公司


<div
class="footer">.footer</div>
pWW上海雲路網絡科技有限公司


 優雅的
Demo
pWW上海雲路網絡科技有限公司


優勢:通俗易懂,容易掌握pWW上海雲路網絡科技有限公司


缺點:能夠想象經過此方法,會添加多少無心義的空標籤,有違結構與表現的分離,在後期維護中將是噩夢,這是堅定不能忍受的,因此你看了這篇文章以後仍是建議不要用了吧。pWW上海雲路網絡科技有限公司


 2)使用 br標籤和其自身的 html屬性pWW上海雲路網絡科技有限公司


這個方法有些小衆,br 有 clear=「all | left | right | none」 屬性pWW上海雲路網絡科技有限公司


 <div class="warp"
id="float2">
pWW上海雲路網絡科技有限公司


<h2>2)使用 br標籤和其自身的
html屬性</h2>
pWW上海雲路網絡科技有限公司


<div class="main
left">.main{float:left;}</div>
pWW上海雲路網絡科技有限公司


<div class="side
left">.side{float:right;}</div>
pWW上海雲路網絡科技有限公司


<br clear="all" />pWW上海雲路網絡科技有限公司


</div>pWW上海雲路網絡科技有限公司


<div
class="footer">.footer</div>
pWW上海雲路網絡科技有限公司


 優雅的
Demo
pWW上海雲路網絡科技有限公司


 優勢:比空標籤方式語義稍強,代碼量較少pWW上海雲路網絡科技有限公司


缺點:一樣有違結構與表現的分離,不推薦使用pWW上海雲路網絡科技有限公司


 3)父元素設置 overflow:hiddenpWW上海雲路網絡科技有限公司


經過設置父元素overflow值設置爲hidden;在IE6中還須要觸發 hasLayout ,例如 zoom:1;pWW上海雲路網絡科技有限公司


 <div class="warp" id="float3"
style="overflow:hidden; *zoom:1;">
pWW上海雲路網絡科技有限公司


<h2>3)父元素設置 overflow
</h2>
pWW上海雲路網絡科技有限公司


<div class="main
left">.main{float:left;}</div>
pWW上海雲路網絡科技有限公司


<div class="side
left">.side{float:right;}</div>
pWW上海雲路網絡科技有限公司


</div>pWW上海雲路網絡科技有限公司


<div
class="footer">.footer</div>
pWW上海雲路網絡科技有限公司


 優雅的
Demo
pWW上海雲路網絡科技有限公司


優勢:不存在結構和語義化問題,代碼量極少pWW上海雲路網絡科技有限公司


缺點:內容增多時候容易形成不會自動換行致使內容被隱藏掉,沒法顯示須要溢出的元素;04年POPO就發現overflow:hidden會致使中鍵失效,這是我做爲一個多標籤瀏覽控所不能接受的。因此仍是不要使用了pWW上海雲路網絡科技有限公司


4)父元素設置 overflow:auto 屬性pWW上海雲路網絡科技有限公司


一樣IE6須要觸發hasLayout,演示和3差很少pWW上海雲路網絡科技有限公司


優勢:不存在結構和語義化問題,代碼量極少pWW上海雲路網絡科技有限公司


缺點:多個嵌套後,firefox某些狀況會形成內容全選;IE中 mouseover
形成寬度改變時會出現最外層模塊有滾動條等,firefox早期版本會無端產生focus等, 請看 嗷嗷的 Demo ,不要使用pWW上海雲路網絡科技有限公司


5)父元素也設置浮動pWW上海雲路網絡科技有限公司


優勢:不存在結構和語義化問題,代碼量極少pWW上海雲路網絡科技有限公司


缺點:使得與父元素相鄰的元素的佈局會受到影響,不可能一直浮動到body,不推薦使用pWW上海雲路網絡科技有限公司


6)父元素設置display:tablepWW上海雲路網絡科技有限公司


 優雅的
Demo
pWW上海雲路網絡科技有限公司


 優勢:結構語義化徹底正確,代碼量極少pWW上海雲路網絡科技有限公司


缺點:盒模型屬性已經改變,由此形成的一系列問題,得不償失,不推薦使用pWW上海雲路網絡科技有限公司


7)使用:after 僞元素pWW上海雲路網絡科技有限公司


須要注意的是 :after是僞元素(Pseudo-Element),不是僞類(某些CSS手冊裏面稱之爲「僞對象」),不少清除浮動大全之類的文章都稱之爲僞類,不過csser要嚴謹一點,這是一種態度。pWW上海雲路網絡科技有限公司


因爲IE6-7不支持:after,使用 zoom:1觸發 hasLayout。pWW上海雲路網絡科技有限公司


 該方法源自於: How To Clear Floats Without Structural MarkuppWW上海雲路網絡科技有限公司


原文所有代碼以下:pWW上海雲路網絡科技有限公司

<style type="text/css">  .clearfix:after {  content: "."; display: block; height: 0; clear: both; visibility: hidden;  }   .clearfix {display: inline-block;}  /* for IE/Mac */   </style> <!--[if IE]> <style type="text/css"> .clearfix {zoom: 1;/* triggers hasLayout */  display: block;/* resets display for IE/Win */} </style>  <![endif]-->  鑑於 IE/Mac的市場佔有率極低,咱們直接忽略掉,最後精簡的代碼以下:pWW上海雲路網絡科技有限公司

 .clearfix:after {content:"."; display:block; height:0; visibility:hidden;
clear:both; }pWW上海雲路網絡科技有限公司


.clearfix { *zoom:1; }pWW上海雲路網絡科技有限公司


 優雅的
Demo
pWW上海雲路網絡科技有限公司


優勢:結構和語義化徹底正確,代碼量居中pWW上海雲路網絡科技有限公司


缺點:複用方式不當會形成代碼量增長pWW上海雲路網絡科技有限公司


 小結pWW上海雲路網絡科技有限公司


經過對比,咱們不難發現,其實以上列舉的方法,無非有兩類:pWW上海雲路網絡科技有限公司


其一,經過在浮動元素的末尾添加一個空元素,設置 clear:both屬性,after僞元素其實也是經過 content
在元素的後面生成了內容爲一個點的塊級元素;pWW上海雲路網絡科技有限公司


其二,經過設置父元素 overflow 或者display:table 屬性來閉合浮動,咱們來探討一下這裏面的原理。pWW上海雲路網絡科技有限公司


在CSS2.1裏面有一個很重要的概念,可是國內的技術博客介紹到的比較少,那就是
Block formatting contexts
(塊級格式化上下文),如下簡稱 BFC。pWW上海雲路網絡科技有限公司


CSS3裏面對這個規範作了改動,稱之爲:flow root,而且對觸發條件進行了進一步說明。pWW上海雲路網絡科技有限公司


那麼如何觸發BFC呢?pWW上海雲路網絡科技有限公司



  • float 除了none之外的值 pWW上海雲路網絡科技有限公司
     
  • overflow 除了visible 之外的值(hidden,auto,scroll
    pWW上海雲路網絡科技有限公司
     
  • display
    (table-cell,table-caption,inline-block)
    pWW上海雲路網絡科技有限公司
     
  • position(absolute,fixed) pWW上海雲路網絡科技有限公司
     
  • fieldset元素

須要注意的是,display:table 自己並不會建立BFC,可是它會產生匿名框(anonymous
boxes),而匿名框中的display:table-cell能夠建立新的BFC,換句話說,觸發塊級格式化上下文的是匿名框,而不是display:table。因此經過display:table和display:table-cell建立的BFC效果是不同的。pWW上海雲路網絡科技有限公司


 fieldset 元素在www.w3.org裏目前沒有任何有關這個觸發行爲的信息,直到HTML5標準裏纔出現。有些瀏覽器bugs(Webkit,Mozilla)提到過這個觸發行爲,可是沒有任何官方聲明。實際上,即便fieldset在大多數的瀏覽器上都能建立新的塊級格式化上下文,開發者也不該該把這當作是理所固然的。CSS
2.1沒有定義哪一種屬性適用於表單控件,也沒有定義如何使用CSS來給它們添加樣式。用戶代理可能會給這些屬性應用CSS屬性,建議開發者們把這種支持當作實驗性質的,更高版本的CSS可能會進一步規範這個。
pWW上海雲路網絡科技有限公司


 pWW上海雲路網絡科技有限公司


BFC的特性:pWW上海雲路網絡科技有限公司


1)塊級格式化上下文會阻止外邊距疊加


當兩個相鄰的塊框在同一個塊級格式化上下文中時,它們之間垂直方向的外邊距會發生疊加。換句話說,若是這兩個相鄰的塊框不屬於同一個塊級格式化上下文,那麼它們的外邊距就不會疊加。pWW上海雲路網絡科技有限公司


2)塊級格式化上下文不會重疊浮動元素


根據規定,一個塊級格式化上下文的邊框不能和它裏面的元素的外邊距重疊。這就意味着瀏覽器將會給塊級格式化上下文建立隱式的外邊距來阻止它和浮動元素的外邊距疊加。因爲這個緣由,當給一個挨着浮動的塊級格式化上下文添加負的外邊距時將會不起做用(Webkit和IE6在這點上有一個問題——能夠看這個測試用例)。 pWW上海雲路網絡科技有限公司


3)塊級格式化上下文一般能夠包含浮動


詳見: W3C CSS2.1 - 10.6.7 'Auto'
heights for block formatting context roots
 pWW上海雲路網絡科技有限公司
  pWW上海雲路網絡科技有限公司


通俗地來講:建立了 BFC的元素就是一個獨立的盒子,裏面的子元素不會在佈局上影響外面的元素,反之亦然,同時BFC任然屬於文檔中的普通流。pWW上海雲路網絡科技有限公司


至此,您或許明白了爲何 overflow:hidden或者auto能夠閉合浮動了,真是由於父元素建立了新的BFC。對於張鑫旭在對《overflow與zoom」清除浮動」的一些認識
一文中對於用包裹來解釋閉合浮動的原理,我以爲是不夠嚴謹的,並且沒有依據。而且說道「Firefox等瀏覽器並無haslayout的概念」,那麼現代瀏覽器是有BFC的,從表現上來講,hasLayout
能夠等同於 BFC。pWW上海雲路網絡科技有限公司


IE6-7的顯示引擎使用的是一個稱爲佈局(layout)的內部概念,因爲這個顯示引擎自身存在不少的缺陷,直接致使了IE6-7的不少顯示bug。當咱們說一個元素「獲得
layout」,或者說一個元素「擁有 layout」 的時候,咱們的意思是指它的微軟專有屬性 hasLayout http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp
爲此被設爲了 true 。IE6-7使用佈局的概念來控制元素的尺寸和定位,那些擁有佈局(have
layout)的元素負責自己及其子元素的尺寸設置和定位。若是一個元素的 hasLayout
爲false,那麼它的尺寸和位置由最近擁有佈局的祖先元素控制。pWW上海雲路網絡科技有限公司


觸發hasLayout的條件:pWW上海雲路網絡科技有限公司



  • position: absolute pWW上海雲路網絡科技有限公司
     
  • float: left|right pWW上海雲路網絡科技有限公司
     
  • display: inline-block pWW上海雲路網絡科技有限公司
     
  • width: 除 「auto」 外的任意值 pWW上海雲路網絡科技有限公司
     
  • height: 除 「auto」 外的任意值 (例如不少人清除浮動會用到
    height: 1%  )
    pWW上海雲路網絡科技有限公司
     
  • zoom: 除 「normal」 外的任意值 (MSDN) http://msdn.microsoft.com/worksh
    ... properties/zoom.asp
    pWW上海雲路網絡科技有限公司
     
  • writing-mode: tb-rl (MSDN) http://msdn.microsoft.com/worksh
    ... ies/writingmode.asp

在 IE7 中,overflow 也變成了一個 layout 觸發器:pWW上海雲路網絡科技有限公司



  • overflow: hidden|scroll|auto 
    這個屬性在IE以前版本中沒有觸發 layout 的功能。 )pWW上海雲路網絡科技有限公司
     
  • overflow-x|-y: hidden|scroll|auto
    (CSS3 盒模型中的屬性,還沒有獲得瀏覽器的普遍支持。他們在以前IE版本中一樣沒有觸發 layout 的功能)

hasLayout更詳細的解釋請參見 old9翻譯的 大名鼎鼎的 《On having
layout》
一文(英文原文:http://www.satzansatz.de/cssd/onhavinglayout.htm),因爲old9博客被牆,中文版地址:pWW上海雲路網絡科技有限公司


IE8使用了全新的渲染引擎,刪除了 hasLayout 本來的功能,所以完全杜絕了不少深惡痛絕的 bug,但 IE8~IE11
經過「document.documentElement.currentStyle.hasLayout」依然能夠得到 hasLayout 的標誌,我寫了一個測試 Demo(IE8 中 zoom:1 返回
false),更詳細的請看《IE8 haslayout = true》pWW上海雲路網絡科技有限公司


IE8-11獲取 hasLayoutpWW上海雲路網絡科技有限公司


綜上所述:


在支持BFC的瀏覽器(IE8+,firefox,chrome,safari)經過建立新的BFC閉合浮動;


在不支持 BFC的瀏覽器
(IE6-7),經過觸發 hasLayout 閉合浮動。


 pWW上海雲路網絡科技有限公司


4、閉合浮動方法——精益求精


上面已經列舉了7種閉合浮動的方法,經過第三節分析的原理,咱們發現其實更多的:display:table-cell,display:inline-block等只要觸發了BFC的屬性值均可以閉合浮動。從各個方面比較,after僞元素閉合浮動無疑是相對比較好的解決方案了,下面詳細說說該方法。pWW上海雲路網絡科技有限公司


.clearfix:after {content:"."; display:block; height:0; visibility:hidden;
clear:both; }pWW上海雲路網絡科技有限公司


.clearfix { *zoom:1; }pWW上海雲路網絡科技有限公司


1) display:block 使生成的元素以塊級元素顯示,佔滿剩餘空間;pWW上海雲路網絡科技有限公司


2) height:0 避免生成內容破壞原有佈局的高度。pWW上海雲路網絡科技有限公司


3) visibility:hidden 使生成的內容不可見,並容許可能被生成內容蓋住的內容能夠進行點擊和交互;pWW上海雲路網絡科技有限公司


4)經過 content:"."生成內容做爲最後一個元素,至於content裏面是點仍是其餘都是能夠的,例如oocss裏面就有經典的
content:"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",有些版本可能content
裏面內容爲空,一絲冰涼是不推薦這樣作的,firefox直到7.0 content:」" 仍然會產生額外的空隙;pWW上海雲路網絡科技有限公司


5)zoom:1 觸發IE hasLayout。pWW上海雲路網絡科技有限公司


經過分析發現,除了clear:both用來清除浮動的,其餘代碼無非都是爲了隱藏掉content生成的內容,這也就是其餘版本的閉合浮動爲何會有font-size:0,line-height:0。pWW上海雲路網絡科技有限公司


 pWW上海雲路網絡科技有限公司


精益求精方案一:pWW上海雲路網絡科技有限公司


相對於空標籤閉合浮動的方法代碼彷佛仍是有些冗餘,經過查詢發現Unicode字符裏有一個「零寬度空格」,也就是U+200B ,這個字符自己是不可見的,因此咱們徹底能夠省略掉 visibility:hidden了pWW上海雲路網絡科技有限公司


.clearfix:after {content:"\200B"; display:block; height:0; clear:both; }pWW上海雲路網絡科技有限公司


.clearfix { *zoom:1; }.pWW上海雲路網絡科技有限公司


精益求精方案二:pWW上海雲路網絡科技有限公司


由Nicolas Gallagher 大溼提出來的,原文:A new
micro clearfix hack
,該方法也不存在firefox中空隙的問題。pWW上海雲路網絡科技有限公司


/* For modern browsers */pWW上海雲路網絡科技有限公司


.cf:before,.cf:after {pWW上海雲路網絡科技有限公司


content:"";pWW上海雲路網絡科技有限公司


display:table;pWW上海雲路網絡科技有限公司


}pWW上海雲路網絡科技有限公司


.cf:after { clear:both; }/* For IE 6/7
(trigger hasLayout) */
pWW上海雲路網絡科技有限公司


.cf { zoom:1; }pWW上海雲路網絡科技有限公司


 須要注意的是:有限公司


上面的方法用到了 
:before僞元素,不少人對這個有些迷惑,到底我何時須要用before呢?爲何方案一沒有呢?其實它是用來處理margin邊距重疊的,因爲內部元素
float 建立了BFC,致使內部元素的margin-top和 上一個盒子的margin-bottom
發生疊加。若是這不是你所但願的,那麼就能夠加上before,若是隻是單純的閉合浮動,after就夠了!並非如同大漠《Clear
Float》
一文所說的:但只使用clearfix:after時在跨瀏覽器兼容問題會存在一個垂直邊距疊加的bug,這不是bug,是BFC應該有的特性。pWW上海雲路網絡科技有限公司

邊距疊加測試.jpgpWW上海雲路網絡科技有限公司


請看優雅的DemopWW上海雲路網絡科技有限公司


進一步瞭解請看:
《clearfix改良及overflow:hidden詳解【譯】》
pWW上海雲路網絡科技有限公司


    在實際開發中,改進方案一因爲存在Unicode字符不適合內嵌CSS的GB2312編碼的頁面,使用方案7徹底能夠解決咱們的需求了,改進方案二等待你們的進一步實踐。方案三、4經過overflow閉合浮動,實際上已經建立了新的
塊級格式化上下文,這將致使其佈局和相對於浮動的行爲等發生一系列的變化,清除浮動只不過是一系列變化中的一個做用而已。因此爲了閉合浮動去改變全局特性,這是不明智的,帶來的風險就是一系列的bug,好比firefox
早期版本產生 focus,截斷絕對定位的層等等。始終要明白,若是單單只是須要閉合浮動,overflow就不要使用,而不是某些文章所說的「慎用」。pWW上海雲路網絡科技有限公司

    前先後後花了三天寫完了這篇文章。若是以爲本文對您有幫助,您的留言就是對我最大的支持,同時因爲精力有限,歡迎指出文中錯誤與不足,共勉之!pWW上海雲路網絡科技有限公司

參考資料:pWW上海雲路網絡科技有限公司

pWW上海雲路

原文連接: http://www.iyunlu.com/view/css-xhtml/55.html

 pWW上海雲路網絡科技有限公原文連接:   

相關文章
相關標籤/搜索