本篇講解的是主要是BFC 可以解決的 margin 重疊問題 ,如對你有幫助 ,請點個贊給個鼓勵,謝謝~ 先來一張W3C標準盒模型的圖片.

margin 屬性介紹
margin 的幾種使用方法,簡單帶過.
margin : top right bottom right ;
margin : top leftright bottom;
margin : topbottom leftright;
margin : topbottomleftright;
1.普通流 margin 百分比設置
<!--css -->
<style>
.container{
background-color: pink;
width:300px;
height:300px;
margin:10px;
display: inline-block;/*為什么這里使用display: inline-block,我在這里先賣個關子,下面會講*/
}
.content{
background-color: #000000;
width:100px;
height:100px;
margin:10%;
}
</style>
<!--html -->
<div class="container">
<div class="content"></div>
</div>
效果如下圖所示

可以看出, top left 方向的 margin 都是30px ( 300 * 10% = 30)。父元素設置display是有原因的,會在下面小節(jié)提到,稍安勿躁。
注意,margin 四個方位的值都是依據父元素的 width(=300px) 計算!
2.絕對定位的 margin 百分比設置
<style>
.container{
background-color: pink;
width:300px;
height:300px;
margin:10px;
display: inline-block;/*為什么這里使用display: inline-block,我在這里先賣個關子,下面會講*/
}
.content{
background-color: #000000;
width:100px;
height:100px;
margin:10%;
position:absolute;
}
</style>

在脫離文檔流(absolute,fixed)的定位元素中(如:小黑塊),則margin百分比值是最近一個有定位設置(relative,absolute,fixed)的父級對象進行絕對定位父元素的width 計算的,若對象父級沒有設置定位屬性(absolute,fixed,relative),則 margin 百分比值是依據 body的 width 計算的。
position:fixed: 固定的參照對像是
可視窗口而并非是body或是父級元素??赏ㄟ^z-index進行層次分級
position:absolute: 脫離文檔流,通過 top,bottom,left,right 定位。選取其最近一個有
定位設置(relative,absolute,fixed)的父級對象進行絕對定位,如果對象的父級沒有設置定位屬性,absolute元素將以body坐標原點進行定位,可以通過z-index進行層次分級。
relative(相對定位): 對象不可層疊、不脫離文檔流,參考自身靜態(tài)位置通過 top,bottom,left,right 定位,并且可以通過z-index進行層次分級。
margin重疊(Collapsing margins)
Collapsing margins,即外邊距折疊,指的是相鄰的兩個或多個外邊距 (margin) 會合并成一個外邊距。margin 折疊 必須發(fā)生在普通流元素中。
1.Collapsing margins 初衷
Collapsing margins 的初衷就是為了讓段落顯示的更加好看。以由幾個段落組成的典型文本頁面為例。第一個段落上面的空間等于段落的上外邊距。如果沒有外邊距合并,后續(xù)所有段落之間的外邊距都將是相鄰上外邊距和下外邊距的和。這意味著段落之間的空間是頁面頂部的兩倍。如果發(fā)生外邊距合并,段落之間的上外邊距和下外邊距就合并在一起,這樣各處的距離就一致了。

2.Collapsing margins 類型
CSS 里面關于折疊的條件:
兩個塊元素要產生**折疊**現象,必須滿足一個必備條件:這兩個元素的 margin 必須是**相鄰**的;那么如果定義相鄰呢,w3c 規(guī)范,兩個 margin 是鄰接的必須滿足以下條件:
- 必須是處于常規(guī)文檔流(非float和絕對定位)的塊級盒子,并且處于同一個 BFC 當中。
- 沒有
inline盒子,沒有空隙,沒有padding和border將他們分隔開。- 都屬于垂直方向上相鄰的外邊距
什么是 BFC? 如何觸發(fā) BFC, 大家可以閱讀
margin 重疊的最直接的解決方法:
讓元素處于不同的BFC屬性下。
1.兄弟元素的 margin 重疊
發(fā)生的前提:在同一個父級塊級容器下
<div class="box1"></div>
<div class="box2"></div>
.box1 {
width: 300px;
height: 300px;
margin-bottom: 10px;
background-color: lightpink;
}
.box2 {
width: 300px;
height: 300px;
margin-top: 10px;
background-color: lightgreen;
}

2.父子元素的 margin 重疊
這個就是剛剛賣關子的地方,可以回退上去看看. 它就屬于父元素的margin重疊.
再舉一個案例:
//style
.first-block {
background: #F44336;
width: 200px;
height: 200px;
}
.second-block {
background: #00BCD4;
width: 200px;
height: 200px;
}
//html
<div class="first-block"></div>
<div class="second-block">
<h2>我是有默認 margin 的 H2元素</h2>
</div>
為什么 first-block 和 second-block 之間會有這么寬的間距?
原因是:外邊距折疊,這個間距是 h2 的上外邊距引起的。
那么我們就可以通過給元素加邊框或者邊距來解決啦(不滿足條件2,來解決 margin 重疊問題),我是不是狠聰明呢?
解決辦法 1:
.second-block {
background: #00BCD4;
width: 200px;
height: 200px;
border:1px solid rgba(0,0,0,0);
}
折疊問題解決了,但是由于有1px的邊框,second-block 看起來會比 first-block 寬一點,沒關系,添加 box-sizing: border-box 屬性可以解決這個問題:再加一句:box-sizing:border-box,將盒子修改成怪異模式即(content+padding+border) ;
解決辦法 2:
.second-block {
background: #00BCD4;
width: 200px;
height: 200px;
overflow:hidden;
}
通過把 overflow 把 second-block 元素形成一個 BFC,完美解決!
3.Collapsing margins 解決方法
解決方法有如下:
1:float、inline-block 元素、絕對定位元素的 margin 不會和垂直方向上其他元素的 margin 折疊 ( 針對 兄弟元素)
注意: float , inline-block元素 , 絕對定位元素 都屬于 BFC元素。
2:創(chuàng)建了塊級格式化上下文(BFC, blocking formatting context )的父元素,比如說overflow:hidden,不和它的子元素發(fā)生 margin 折疊 (針對 父子元素)。
3:給父元素添加以下內容之一都可以避免發(fā)生 margin 重疊 。如 添加 border或者使用 padding來代替 margin。(針對 父子元素)
案例解決方法:
.container{
background-color: pink;
width:300px;
height:300px;
margin:10px;
/*處理margin 重疊的方法*/
/*overflow: hidden | scroll | auto;*/
/*display: inline-block |flex | table | inline-block | inline-flex | inline-table | list-item | table-caption | table-cell*!*/
/*float: left | right;*/
/*position:absolute |fixed;*/
display: inline-block;
}
.content{
background-color: #000000;
width:100px;
height:100px;
margin:10%;
}
雖然有方法解決這個問題。但是目前最好的解決方案是回避這個問題。也就是,不要給指定元素添加具有指定寬度的內邊距或外邊距,而是嘗試將內邊距或外邊距添加到元素的父元素和子元素。
更多內容可以訂閱本人微信公眾號,一起開啟前端小白進階的世界!
