浮動 三 再見,浮動!

做爲終結篇,居然是消滅它。。。css

好吧,仍是先開始吧。html

一. clear屬性

說道清除浮動,你們恐怕第一個想到的就是clear屬性吧。該屬性的官方說明以下:面試

屬性名: clear
值: none | left | right | both | inherit
初始值: none
繼承性: 無
應用對象:block-level元素

它指明瞭block-level box(看第21條)不但願本身的 left/ right / both與前面的float box相毗鄰。要注意的是,這裏清除的是排在block-level box前面的float box,與後面的float box不相干啊。有疑惑的童鞋請翻翻這篇文章的上半部分。chrome

  • 設爲 left 會使得該box的上邊框邊緣(top border edge)不高於在它以前的任何向左浮動的float box的下邊緣(看第24條)
  • 設爲 right 會使得該box的上邊框邊緣(top border edge)不高於在它以前的任何向右浮動的float box的下邊緣
  • 設爲 both 會使得該box的上邊框邊緣(top border edge)不高於在它以前的任何float box的下邊緣
  • 設爲 none 那就是啥也不作


以上這些都是咱們經過代碼調節能夠直觀看見的現象,實際背後有更深層的東西值得咱們去挖掘。編程

二. 「清除」引入的條件、「清除」達到的效果、清除公式

1. 條件瀏覽器

首先問個問題: 是否是隻要clearence設爲非none,就真的會發生浮動清除呢?bash

固然不是!測試

若是clearence設爲非none, css可能會引入清除。決定是否引入還得看block-level box在沒有設置clearence(或者說clearence爲none)的狀況下所處的位置。ui

假設block-level box的clearence設爲left。如今重置它的clearence爲none,看看它的上邊框邊緣是否高於它以前的任何向左浮動的float box的下邊緣。若是高於,則引入清除。spa

2. 效果

看過前幾篇浮動的文章的童鞋都知道,float box可能會與block-level box並排,產生「圍繞現象」。那麼清除浮動帶來的效果就是 block-level box會流動到float box之下,若block-level box與其餘box產生了margin重疊, 重疊現象也會消失。

對比一下,或許更清楚!

例一 無清除

  1. <html>
      <head>
      <style type="text/css">	
    	.parent{
    		width:500px;
    		height:auto;
    		margin:20px auto 0;
    		padding:10px;
    		line-height:30px;
    		font-family:"Times New Roman",Georgia,Serif;
    		border:solid 2px rgba(247, 79, 79, 0.56);
    	}
    	.float-child{
    		width:100px;
    		height:50px;
    		float:left;
    		margin-right:10px;
    		box-sizing:border-box;
    		background:rgba(247, 79, 79, 0.56);
    	}	
    	.normal-child{
    		width:350px;
    		border:solid 1px rgba(247, 79, 79, 0.56);
    		margin-bottom:5px;
    		padding-left:5px;
    	}
    	.first-block{
    		margin-bottom:10px;
    	}
    	.second-block{
    		margin-top:20px;
    	}
      </style>
      </head>
    <body>
      <div class='parent'>
        <div class='normal-child first-block'>first block-level box</div>
        <div class='float-child'></div>
    	<div class='normal-child second-block'>second block-level box</div>
      </div>
    </body>
    </html>
    複製代碼
    chrome上的效果:


float box看上去徹底就是一個土匪嘛,很霸道的擋住第二個block-level box!

另外,第一個block-level box與第二個block-level box也產生了margin重疊,看個像素圖。

能夠看到,第一個block-level box與第二個block-level box之間的距離取margin的最大值20px,它們的margin發生了重疊。

再去看看清除帶來的變化。

例二 引入清除

在例一的基礎上修改.second-block類,具體以下:

.second-block{
		margin-top:20px;
                clear:left;
	}
複製代碼

登登登~~~「清除」上場,效果槓槓滴!

第二個block-level box不只成功的擺脫了float 土匪,還與第一個block-level box劃清了界限,margin沒有重疊,互不干擾,清的很乾淨嘛!

由此,可看出清除就如同在block-level box的上方加了必定高度的空白,這會使得block-level box移動到float box之下,並阻止了margin重疊。

看到這,有木有童鞋對block-level box下移的計算過程感興趣?雖然說在實際編程中沒啥用處,可是能夠在面試官面前裝大神。。。。好吧,我接着講了,不感興趣的童鞋直接略過下節。

3. 清除公式

用過清除的都知道,block-level box雖然說會移動到float box下方,但也不是隨意下移的,它每次都會保證border的上邊緣與位置最低的被清除float box的下邊緣齊平。這是如何作到的呢?計算出block-level box的上邊緣與位置最低的被清除float box的下邊緣齊平所須要的清除距離(設爲C),而後將block-level box下移C。

距離又是怎麼算出來的呢?這裏有個清除公式。

假設在html文檔裏有以下幾個元素:第一位是margin-bottom爲M1的block B1,第二位是高度爲H的float box,第三位是margin-top爲M2的block B2。B1和B2均沒有子box,也沒有設置padding或border。另外,B2不爲空,且clear爲both。那麼它們在瀏覽器上應該表現成醬紫:

由於要引入清除,那麼第二個block box必須知足:上邊框邊緣高於它以前的任何向左浮動的float box的下邊緣,也就是:

max(M1,M2) < M1 + H

看上文,咱們知道:清除須要保證B2的border的上邊緣與位置最低的被清除float box的下邊緣齊平,也就是:

F的下邊緣 = B2的border的上邊緣

M1 + H = M1 + C + M2 (注:M1和M2此時是不會重疊的)

C = M1 + H - M1 - M2

= H - M2

由此,咱們知道清除距離

C = H - M2

也許有愛思考的童鞋問道:若是float box有上下margin怎麼辦?

此時的C = (H + 上margin + 下margin) - M2。

爲啥?哈哈,這是由於float box不會與任何box發生margin重疊,因此呢,在有上下margin時得加上margin。

是否是沒啥鳥用,^ ^ ~~~

三. 你們口中的清除

常看到某些博文寫到,如何清除box內的浮動,清除浮動的N種方法,balabala......一大堆。實際上標準的清除浮動只能清除float box下面的第一個block-level box。

爲何會想到要清除box內的浮動?我想大概是由於某個block box的子float box跑到該block box的外面去了,一些童鞋覺得是浮動搞得鬼。

其實這不徹底怪浮動。

每一個box的高度計算是要遵循必定的規則。overflow爲visible,height爲auto的block box在計算高度時會忽略子box中的float box的高度,由此形成float box的下邊緣跑到block box以外。

還有相似清除浮動的N種方法,大部分是不明白這裏面的規則而寫的hack方法,這些奇怪的清除方式經常會產生一些不易察覺的bug,你們仍是少用爲妙。知道背後的機制,再給出正確的解決辦法,纔是終極之道啊!

浮動終於終於終於寫完了,真是大頭啊,花了很多時間整理。接下來要去啃下一個大骨頭了,byebye啦。

ps: 本文中的例子均是在chrome 49.0上測試。

相關文章
相關標籤/搜索