天天看點

CSS垂直外邊距合并和CSS清除浮動

以下為文檔内容:

外邊距合并指的是,當兩個垂直外邊距相遇時,它們将形成一個外邊距。

合并後的外邊距的高度等于兩個發生合并的外邊距的高度中的較大者。

外邊距合并

外邊距合并(疊加)是一個相當簡單的概念。但是,在實踐中對網頁進行布局時,它會造成許多混淆。

簡單地說,外邊距合并指的是,當兩個垂直外邊距相遇時,它們将形成一個外邊距。合并後的外邊距的高度等于兩個發生合并的外邊距的高度中的較大者。

當一個元素出現在另一個元素上面時,第一個元素的下外邊距與第二個元素的上外邊距會發生合并。請看下圖:

CSS垂直外邊距合并和CSS清除浮動

親自試一試

當一個元素包含在另一個元素中時(假設沒有内邊距或邊框把外邊距分隔開),它們的上和/或下外邊距也會發生合并。請看下圖:

CSS垂直外邊距合并和CSS清除浮動

親自試一試

盡管看上去有些奇怪,但是外邊距甚至可以與自身發生合并。

假設有一個空元素,它有外邊距,但是沒有邊框或填充。在這種情況下,上外邊距與下外邊距就碰到了一起,它們會發生合并:

CSS垂直外邊距合并和CSS清除浮動

如果這個外邊距遇到另一個元素的外邊距,它還會發生合并:

CSS垂直外邊距合并和CSS清除浮動

這就是一系列的段落元素占用空間非常小的原因,因為它們的所有外邊距都合并到一起,形成了一個小的外邊距。

外邊距合并初看上去可能有點奇怪,但是實際上,它是有意義的。以由幾個段落組成的典型文本頁面為例。第一個段落上面的空間等于段落的上外邊距。如果沒有外邊距合并,後續所有段落之間的外邊距都将是相鄰上外邊距和下外邊距的和。這意味着段落之間的空間是頁面頂部的兩倍。如果發生外邊距合并,段落之間的上外邊距和下外邊距就合并在一起,這樣各處的距離就一緻了。

CSS垂直外邊距合并和CSS清除浮動

注釋:隻有普通文檔流中塊框的垂直外邊距才會發生外邊距合并。行内框、浮動框或絕對定位之間的外邊距不會合并。

注釋:隻有普通文檔流中塊框的垂直外邊距才會發生外邊距合并。行内框、浮動框或絕對定位之間的外邊距不會合并。

  在css2.1中,水準的margin不會被折疊。 

  垂直margin可能在一些盒模型中被折疊: 

     1、在正常文檔流中,2個或以上的塊級盒模型相鄰的垂直margin會被折疊。 

      最終的margin值計算方法如下: 

        a、全部都為正值,取最大者;

        b、不全是正值,則都取絕對值,然後用正值減去最大值;

        c、沒有正值,則都取絕對值,然後用0減去最大值。

      注意:相鄰的盒模型可能由DOM元素動态産生并沒有相鄰或繼承關系。 

    2、相鄰的盒模型中,如果其中的一個是浮動的(floated),垂直margin不會被折疊,甚至一個浮動的盒模型和它的子元素之間也是這樣。 

    3、設定了overflow屬性的元素和它的子元素之間的margin不會被折疊(overflow取值為visible除外)。 

    4、設定了絕對定位(position:absolute)的盒模型,垂直margin不會被折疊,甚至和他們的子元素之間也是一樣。 

    5、設定了display:inline-block的元素,垂直margin不會被折疊,甚至和他們的子元素之間也是一樣。 

    6、如果一個盒模型的上下margin相鄰,這時它的margin可能折疊覆寫(collapse through)它。在這種情況下,元素的位置(position)取決于它的相鄰元素的margin是否被折疊。 

        a、如果元素的margin和它的父元素的margin-top折疊在一起,盒模型border-top的邊界定義和它的父元素相同。

        b、另外,任意元素的父元素不參與margin的折疊,或者說隻有父元素的margin-bottom是參與計算的。如果元素的border-top非零,那麼元素的border-top邊界位置和原來一樣。

      一個應用了清除操作的元素的margin-top絕不會和它的塊級父元素的margin-bottom折疊。 

      注意,那些已經被折疊覆寫的元素的位置對其他已經被折疊的元素的位置沒有任何影響;隻有在對這些元素的子元素定位時,border-top邊界位置才是必需的。 

    7、根元素的垂直margin不會被折疊。

    浮動的塊級元素的margin-bottom總是與它後面的浮動塊級兄弟元素(floated next in-flow block-level sibling)的margin-top相鄰,除非那個同級元素使用了清除操作。 

  浮 動的塊級元素的margin-top和它的第一個浮動塊級子元素(floated first in-flow block-level child)的margin-top相鄰(如果該元素沒有border-top,沒有padding-top,并且子元素沒有使用清除操作)。 

  浮動的塊級元素的margin-bottom如果符合下列條件,那麼它和它的最後一個浮動塊級子元素的margin-bottom相鄰(如果該元素沒有指定padding-bottom或border): 

      a、指定了height:auto

      b、min-height小于元素的實際使用高度(height)

      c、max-height大于元素的實際使用高度(height)

  如 果一個元素的min-height屬性設定為0,那麼它所擁有的margin是相鄰的,并且它既沒有border-top和border- bottom,也沒有padding-top和padding-bottom,它的height屬性可以是0或auto,它不能包含一個内聯的盒模型 (line box),它所有的浮動子元素(如果有的話)的margin也都是相鄰的。 

  當一個元素擁有的margin折疊了,并且它使用了清除操作,那麼它的margin-top會和緊随其後的兄弟元素的相鄰margin折疊,但結果是它的margin将無法和其塊級父元素的margin-bottom折疊。 

  折疊操作是以padding、margin、border的值為基礎的(即在浏覽器解析所有這些值之後),折疊後的margin計算将覆寫已使用的不同margin的值。

如何解決

  W3C的CSS2.1 定義了幾種情況,簡單為元素添加邊框或者間距(border or padding)就可以不使邊距重疊。

  我們 添加一個小的間距:

   #box {background: #F80; margin: 10px; padding: 1px 0;} 

關于CSS清除浮動的方式:clear屬性和 overflow:hidden;

當元素浮動的時候,它自身将脫離正常靜态流文檔,但是它仍然會占據着位置。我個人更喜歡把它想象成兩層模型,一層是浮動層,一層是靜态層,而兩層内的元素,在俯視的角度上,它們是“可接觸的”。

最簡單的測試就是:

<html>

<head>

<title></title>

<style type="text/css">

ul

{

background: blue;

margin: 0;

overflow: hidden;

}

ul li {

width: 50px;

height: 50px;

background: red;

margin-right: 10px;

float: left;

}

</style>

</head>

<body>

<ul>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

</ul>

<p>asdfasf</p>

</body>

</html>

P标簽内的内容被擠到了右邊,而不是從左邊開始,說明FLOAT即使脫離了文檔流也占據了“浮動層”的空間(經過了一些查詢我發現自己定義的“浮動層”空間,實際上的名詞叫做,行框空間,浮動的元素會占據相鄰非浮動元素的行框空間,而行框的概念是:行框是指本行的一個虛拟的矩形框,是浏覽器渲染模式中的一個概念,并沒有實際顯示。行框高度等于本行内所有元素中行内框最大的值。當有多行内容時,每行都會有自己的行框。是以,P标簽的内容會被浮動框給擠到一邊,當内容超過了浮動框的高度時,又重新回到了正常的位置,就像圖像的文字環繞效果)

有時候,當我們沒有設定父元素的高度的時候,如果子元素浮動了,它就沒有了高度,影響内容。為此我們需要清除浮動,達到不影響内容高度的效果,有些人可能不明白清除浮動的概念,既然要讓元素浮動,為什麼又要清除浮動?其實這兩個詞針對的對象是不同的,浮動是針對需要浮動的對象也就是元素,而清除浮動,是針對被浮動元素所影響的對象(元素)。比如上面的例子,浮動的是LI,需要清除浮動的是UL,因為UL沒有設定高度,如果LI浮動起來了。那麼UL裡面沒有内容。高度就會變為0,一般這種用法是在UL裡面加上overflow:hidden。

這種做法的原理是BFC内容,有興趣可以了解下。  當需要确認overflow:hidden的時候,必須知道它的内容高度,這是一個反布局常識。進而達到了清除浮動的目的。

其實還有另外一個我自己覺得很偏門的方式。隻适用于某些情況,那就是在需要清除浮動的元素中添加浮動!比如float:left 或者right;原理我猜也是一樣,當浮動的時候,需要計算浮動的内容體積,進而達到同樣的效果,隻是為了清除浮動而讓元素浮動起來,這是很不可取的,這裡隻是稍微談一下。

至于clear:both的意思很明确,清除左右兩側浮動,這個用法針對具體情況選擇,到底是overflow還是clear ,一般overflow是針對子元素浮動,clear則是同輩元素之間的處理。

但是有一點我沒搞明白的是,clear:right這個屬性有時候無效,比如 UL LI裡面,我把第三個LI設定為celar:right,結果後面的元素還是浮動起來了,但如果在LI 與LI之間插入 一個新元素比如P,在對P添加clear:right則有效,我想應該跟BFC内容有關,有空我也得去研究下它的神奇之處

以前沒學深,覺得前端沒什麼,現在也沒學深,但是至少知道了,前端水很深。不過有挑戰才有動力