1. 程式人生 > >由父子元素margin說開——外邊距塌陷(margin-collapse)

由父子元素margin說開——外邊距塌陷(margin-collapse)

佈局時往往要遇到div巢狀顯示效果,如下:


假設藍色的為div1,黃色的為div2,為了實現上圖所示佈局,我的想法是為demo1設定margin:0px auto; demo2位置margin:30px,auto;

程式碼如下:

<span style="font-size:14px;"><!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<style>
		body{
			background-color: darkgray;
		}
		*{
			margin:0px;
			padding: 0px;
		}
		.div1{
			width:800px;
			height: 200px;
			background-color: cornflowerblue;
			margin:0px auto;
		}
		.div2{
			width:80%;
			height: 10%;
			background-color: wheat;
			margin: 30px auto;
		}
		</style>
	</head>

	<body>
      <div class="div1">
      	 <div class="div2">     	 	
      	 </div>
      </div>
	</body>

</html></span>

然而在瀏覽器裡的結果顯示如下:

div1隨著div2往下走了30px,而div2相對div1的位置卻沒有變,這是為什麼呢?

看上去父子元素的margin-top合併了。流內塊級元素的top與bottom外邊距有時會合並(塌陷)為單個外邊距(合併後最大的外邊距),這樣的現象稱之為外邊距塌陷(margin collapsing 塌陷只存在與相鄰的垂直外邊距,即只涉及到margin-top/bottom,水平(margin-left/rignt無) 以下三種情況會出現外邊距塌陷:      1.      毗鄰兄弟元素之間:
  • 若兩者都為正外邊距以最大的外邊距為準;
  • 若存在負邊距, 合併後的外邊距為最大正外邊距減去絕對值最大的負邊距;
  • 若無正外邊距,則用0減去絕對值最大負邊距。
     2.      父元素與第一個/最後一個子元素之間 如果塊元素的 margin-top 與它的第一個子元素的margin-top 之間沒有 border、padding、inline content、 clearance 來分隔,或者塊元素的 margin-bottom 與它的最後一個子元素的margin-bottom 之間沒有 border、padding、inline content、height、min-height、 max-height 分隔,那麼外邊距會塌陷。子元素多餘的外邊距會被父元素的外邊距截斷。
  • margin-top:

          父元素無 border、padding、inline content(例子中::before偽元素為絕對定位脫離正常流,所以不算inline content) 、 clearance,父子元素的margin-top塌陷,此時子元素margin-top:30px,使得父子元素同時移動。
  • margin-bottom:
               若給父元素新增height,且height不能為auto,只能為絕對數值或者百分比(margin-top不受height影響),則塌陷效果被消除。        若給父元素新增min-height,則父元素底部外邊距依然受子元素影響,需通過border/padding/inline content/overflow消除。       3.     自身合併         一個盒的top和bottom margin,該盒沒有建立一個新的塊格式化上下文並且'min-height'的計算值為0,'height'的計算值為0或者'auto',並且沒有流內子級
官方文件Note: - 一個浮動的盒與任何其它盒之間的margin不會合並(甚至一個浮動盒與它的流內子級之間也不會) - 建立了新的塊格式化上下文的元素(例如,浮動盒與'overflow'不為'visible'的元素)的margin不會與它們的流內子級合併 - 絕對定位的盒的margin不會合並(甚至與它們的流內子級也不會) - 內聯盒的margin不會合並(甚至與它們的流內子級也不會) - 一個流內塊級元素的bottom margin總會與它的下一個流內塊級兄弟的top margin合併,除非兄弟有空隙 - 一個流內塊級元素的top margin會與它的第一個流內塊級子級的top margin合併,如果該元素沒有top border,沒有top padding並且該子級沒有空隙 - 一個'height'為'auto'並且'min-height'為0的流內塊級盒的bottom margin會與它的最後一個流內塊級子級的bottom margin合併,如果該盒沒有bottom padding並且沒有bottom border並且子級的bottom margin不與有空隙的top margin合併 - 盒自身的margin也會合並,如果'min-height'屬性為0,並且既沒有top或者bottom border也沒有top或者bottom padding,並且其'height'為0或者'auto',並且不含行盒,並且其所有流內子級的margin(如果有的話)都合併了        解決父子元素的外邊距塌陷方法:
  • border:1px solid transparent;
  • padding;
  • float:left/right
  • position:absolute
  • display:inline-block
  • overflow:hidden/auto
https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing