tip:為能更直觀地學習,本文章已省略部分 css 樣式程式碼。
我相信下面的情形大家在日常工作中常常碰到:在製作靜態頁面中,為了頁面整體的協調與美觀,我們想讓子盒子 image-div 的上邊沿距離父盒子 header-div 的上邊沿有一定間距。
現頁面效果:
目標頁面效果:
為了達成上圖的效果,我們首先就能想到給子盒子設定一個上外邊距:
<style>
.image-div { /*子盒子*/
margin-top:25px;
}
</style>
讓我們來看看結果如何呢?
結果和我們所預料的並不相同,子盒子 image-div 並沒有和父盒子 header-div 的上邊沿形成一定的間距。這兩個盒子竟然一起往下移動了,多出了紅框區域。
而這種現象,就是 CSS 中常遇到的“邊距塌陷”問題中的一種。
邊距塌陷
流內塊級元素的 top 與 bottom 外邊距有時會合並(塌陷)為單個外邊距(合併後最大的外邊距),這樣的現象稱之為外邊距塌陷(margin collapsing)。
導致邊距塌陷的原因是外邊距,有以下四種情況計算情況:
- 如果都是正數,則取最大值
- 如果相同,則取其中之一
- 如果有正有負,則取最大的正數加上最小的負數之和
- 如果都是負數,則取最小值。
相鄰(兄弟)盒子之間的塌陷
在 CSS 當中,相鄰兩個兄弟盒子的外邊距區域是公共的,這會導致相鄰兄弟盒子之間的邊距出現塌陷情況。
下圖是相關示例,設定div1盒子的下邊距,另設定下方 div2 盒子的上邊距:
<style>
#block1 {
margin-bottom: 20;
}
#block2 {
margin-top: 10;
}
</style>
<div id = "block1">div1</div>
<div id = "block2">div2</div>
在瀏覽器開發者工具先看 div1 的 margin 區域(紅框):
div2 的 margin 區域(綠框區域):
對應情況:兩個盒子之間的外邊距如果都是正數,則取最大值。
下方為示例 2,我們將示例 1 中的外邊距改為負數:
<style>
#block1 {
margin-bottom: -20;
}
#block2 {
margin-top: -10;
}
</style>
<div id = "block1">div1</div>
<div id = "block2">div2</div>
兩個盒子的重疊距離為兩個負數中最小的數“-20px”(絕對值最大 |-20px|)。
解決方法
如果想要避免這種塌陷,可以通過下面兩種方法解決:
- 只給其中一個盒子設定外邊距
- 給兩個盒子分別套一個父盒子,父盒子屬性設定為 overflow:hidden,同時讓父盒子是密閉區域,從而觸發 BFC
父子盒子之間的塌陷
然而設定父盒子也不是萬全的,當出現以下情況時外邊距會塌陷:
- 塊元素 的 margin-top 與 它的第一個子元素 的 margin-top 之間沒有 border、padding、inline content、clearance 來分隔。
- 塊元素 的 margin-bottom 與 它的最後一個子元素 的 margin-bottom 之間沒有 border、padding、inline content、height、min-height、max-height 分隔。
同時,如果父子公用一段上邊距區域,比如父盒子沒有上邊距時,子盒子設上邊距。這時子盒子帶著父盒子向下移動(相當於給父盒子設定外邊距)就會產生盒子塌陷。
<style>
*{
margin:0px;
padding: 0px;
}
.div1{
width:300px;
height: 200px;
background-color: cornflowerblue;
margin:0px;
}
.div2{
background-color: wheat;
margin: 30px;
}
</style>
<div class="div1">
<div class="div2">
div2
</div>
</div>
父元素不設定外邊距,第一個子元素設定 margin:30px,會發現父元素與子元素一起往下移動了 30px:
解決方法
想要解決這種塌陷的核心辦法是把父子盒子分隔開。我們可以給父盒子設定邊框或者內邊距,或者給父盒子標籤新增 overflow:hidden 屬性,通過觸發 BFC 規則,也就是塊級格式上下文,把父級渲染成一個獨立區域,從而解決父子盒子之間的塌陷問題。
BFC 規則觸發方式:
- float 不為 none
- overflow 不為 visible(常用 overflow:hidden)
- position 為 fixed,absolute
- display 為 flex,inline-block,table-cell
當然,在選擇塌陷的解決方案時,應依據具體的情境,不能所有情況都使用相同的方案,否則會造成其他問題的出現哦~
那麼,在我們學習以上知識後,就能清晰地知道開頭引入的問題正是父子盒子間的塌陷,我們可以通過觸發 BFC 規則(僅其中一種方案)來解決:
<style>
.image-div { /*子盒子*/
margin-top:25px;
}
.header-div { /*父盒子*/
overflow:hidden; /*觸發bfc*/
}
<style>
以上就是 CSS 盒子邊距常見的塌陷與解決辦法,希望能夠對你有所幫助。