1. 程式人生 > >CSS外邊距屬性,深入理解margin

CSS外邊距屬性,深入理解margin

需要 AD result 左右 定位 IT 條件 表格 group

margin

<iframe height=‘265‘ scrolling=‘no‘ title=‘margin‘ src=‘//codepen.io/wmui/embed/zWEzEg/?height=265&theme-id=0&default-tab=result&embed-version=2‘ frameborder=‘no‘ allowtransparency=‘true‘ allowfullscreen=‘true‘ style=‘width: 100%;‘>See the Pen margin by wmui (@wmui) on CodePen.

該屬性用於設置元素的外邊距,外邊距是透明的,默認值0。這是一個簡寫屬性,屬性值最多為4個,例如margin: 10px 15px 10px 15px

,分別表示上外邊距、右外邊距、下外邊距、左外邊距。屬性值也可以是3個,例如margin: 10px 15px 10px,表示上外邊距、左右外邊距、下外邊距。屬性值可以為2個,例如margin: 10px 15px,表示上下外邊距、左右外邊距。屬性值可以為1個,例如margin: 10px,表示四邊外邊距。外邊距也可以單獨設置,margin-top上外邊距,margin-right右外邊距,margin-bottom下外邊距,margin-left做外邊距。屬性值可以是auto,瀏覽器自動計算外邊距,塊級元素會水平居中顯示,如例1,至於為何水平方向居中,垂直方向未居中,這個下面細說。屬性值可以是百分比,百分比是基於父元素的寬度
計算的,在例2中為子元素設置了margin: 50%。屬性值可以是CSS長度單位,值可以是負值。屬性值可以是inherit

外邊距疊加

說明:普通文檔流中,垂直排列的兩個塊級盒子(非父子),他們的上外邊距或者下外邊距會出現疊加,會以兩者中外邊距較大的那個為準,左右外邊距不會疊加。

情況一:上面的例3和例4演示了這個現象,例3margin: 50px,例4margin: 30px,最後兩個盒子之間的距離為50px,要想發生疊加需要滿足以下條件:

1.只發生在塊級元素且是普通流
2.只發生在垂直方向上

情況二:上面的例2中父子嵌套的兩個盒子,父元素和第一個子元素或最後一個子元素也會發生疊加效果,在例2中大盒子的外邊距默認為0,而裏面的小盒子上外邊距50%(即100px),最終兩個盒子的上外邊距都是100px,父子嵌套的盒子需要滿足以下條件才會發生外邊距疊加:

  1. 父元素非BFC元素
  2. 父元素沒有padding-top值
  3. 父元素沒有border-top值
  4. 父元素和第一個子元素間沒有inline元素間隔

細心觀察發現下外邊距沒有發生疊加,margin-bottom發生疊加需要滿足另一個條件,上面的第四條改為:父元素和最後一個子元素之間沒有inline元素分隔,以及父元素沒有height、min-height、max-height限制。

情況三:如果一個盒子沒有任何內容也沒有高度,這個盒子真身也會出現外邊距疊加,例如:

<div style="margin: 30px 0;"></div>

這個盒子的上下邊距最終是30px,需要滿足以下條件空盒子才會發生疊加:

1.沒有border
2.沒有padding
3.沒有內容和高度

margin: auto無法實現垂直居中

拿例1先說,為什麽能實現水平居中?這是因為子盒子是一個塊級元素,它的寬度默認是等於父盒子的寬度,於是子盒子和父盒子之間就有了聯系,當給子盒子固定寬度後,margin: auto能平分剩余空間

在垂直方向上,子盒子的初始高度是不確定的,它是根據內容的高度撐開的,這樣父盒子和子盒子就無法建立聯系,所以margin: auto在垂直方向上會被重置為0,初始高度不等於設置的高度。

margin: auto無法實現圖片水平居中

類似塊級元素無法實現垂直居中的原因,圖片的寬度默認等於自身,無法和父盒子建立聯系,所以左右的外邊距會被重置為0。解決方法,給圖片設置display: block讓圖片容器占滿父盒子

行內元素垂直外邊距無效

對於行內元素(inline),垂直方向上的排列布局是通過line-height, vertical-align來影響的,margin值在垂直方向不會影響他們,但是水平方向可是有效的。還有一些元素,如<thead>, <tbody>, <tfoot>, <tr>, <th>, <td>, <colgroup>這些和表格相關的元素設置margin是無效的

理解BFC

EFC(Block Formatting Content),塊級格式化上下文,可簡單理解為塊級盒子在頁面中的一塊渲染區域,這塊區域可以看做一個獨立的容器,容器裏面的元素不會影響到外邊的元素,網頁布局常見的文檔流有普通文檔流、浮動流和定位流三種,FC就是普通流。

BFC觸發條件

  1. 元素的float值不為none
  2. overflow值不為visible
  3. display值為inline-block、table-cell、table-caption
  4. position值為absolute、fixed

滿足上面的任一個條件都可觸發BFC

BFC的作用

<iframe height=‘265‘ scrolling=‘no‘ title=‘BFC‘ src=‘//codepen.io/wmui/embed/bvoQZj/?height=265&theme-id=0&default-tab=result&embed-version=2‘ frameborder=‘no‘ allowtransparency=‘true‘ allowfullscreen=‘true‘ style=‘width: 100%;‘>See the Pen BFC by wmui (@wmui) on CodePen.

作用1:觸發元素的BFC,使該元素不被浮動元素覆蓋

例1中黃色的盒子浮動了,導致遮蓋住了普通流中的紅色盒子,此時只要觸發紅色盒子的BFC,黃色盒子就不會覆蓋紅色盒子了。

作用2:包含浮動元素

在例2中,紅色父盒子在普通流中,黃色子盒子浮動了,父盒子無法包圍子盒子,觸發父盒子的BFC,使父盒子包圍子盒子

作用3: 阻止外邊距疊加

在例3中是常見的外邊距疊加情況,觸發任一個盒子的BFC,即可阻止外邊距疊加,但並不是只有觸發BFC才能阻止疊加。

有一種情況有些特殊,當使用overflow: hidden阻止疊加時,需要為子盒子的父元素設置這一屬性,例如:

 <div style="margin-bottom: 20px;">TEST</div>
 <div style="overflow: hidden">
  <div style="margin-bottom: 20px;">TEST</div>
</div>

阻止外邊距疊加

除了觸發BFC可以阻止外邊距疊加,還有其他方法,上面說過觸發外邊距疊加需要滿足一些條件,我只要違背那些條件自然就可以阻止外邊距疊加了。對於父子嵌套疊加,我可以為父元素設置border或padding,也可以添加一個行內元素作為第一個子元素(必須要有內容),還可以觸發子元素或父元素的BFC。對於非父子嵌套的外邊距疊加,這其實是一種正常的布局效果,如果非要阻止疊加,那就觸發BFC,設置border或padding是不能阻止其疊加的,只有觸發BFC

CSS外邊距屬性,深入理解margin