外边距折叠
块级元素的上外边距和下外边距有时会合并(或折叠)为一个外边距,其大小取其中的最大者,这种行为称为外边距折叠(margin collapsing),有时也翻译为外边距合并。
<!-- 外边距折叠演示 -->
<div class="collapesd-test">
<div id="top-div"></div>
<div id="bottom-div"></div>
</div>
.collapesd-test {
margin: 20px;
border: 1px solid #808080;
}
#top-div {
width: 50px;
height: 50px;
margin-bottom: 50px;
background-color: #808080
}
#bottom-div {
width: 100px;
height: 100px;
margin-top: 30px;
background-color: #100100;
}
以上代码会产生外边距折叠问题,#top-div
与 #bottom-div
之间分别定义了外边距50px
与30px
,而实际上加载时两个div之间的边距为50px
。
会发生外边距折叠的三种基本情况
相邻元素之间
毗邻的两个元素之间的外边距会折叠(除非后一个元素需要清除之前的浮动)。
情况如上图。
父元素与其第一个或最后一个子元素之间
如果在父元素与其第一个子元素之间不存在边框、内边距、行内内容,也没有创建块格式化上下文、或者清除浮动将两者的 margin-top 分开;或者在父元素与其最后一个子元素之间不存在边框、内边距、行内内容、height
、min-height
、max-height
将两者的 margin-bottom
分开,那么这两对外边距之间会产生折叠。此时子元素的外边距会“溢出”到父元素的外面。
<!-- 父元素与子元素上下边距折叠 -->
<div class="collapesd-test">
<div id="father-div">
<div id="child-div"></div>
</div>
</div>
#father-div {
background-color: #100100
}
#child-div {
width: 50px;
height: 50px;
margin: 50px;
background-color: #808080
}
空的块级元素
如果一个块级元素中不包含任何内容,并且在其 margin-top
与 margin-bottom
之间没有边框、内边距、行内内容、height、min-height
将两者分开,则该元素的上下外边距会折叠。
解决方案:
1. 设置padding或者border
如果把div
看做是细胞,padding
和border
就好比细胞膜,因为没有东西阻隔外边距之间互相渗透,导致折叠。
举第三种情况为例,为#empty-div添加padding属性,即可避免外边距折叠。
CSS
#empty-div {
margin: 50px;
padding: 1px;
}
2. 触发BFC
BFC:块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。
简单来说,BFC规定了内部块级元素如何布局。
以下方式都可以触发BFC:
- 根元素或包含根元素的元素(
html
) - 浮动元素(元素的
float
不为none
) - 绝对定位元素(元素的
position
为absolute
或fixed
) - 行内块元素(元素的
display
为inline-block
) - 表格单元格(元素的
display
为table-cell
,HTML表格单元格默认为该值) - 表格标题(元素的
display
为table-caption
,HTML表格标题默认为该值) - 匿名表格单元格元素(元素的
display
为table
、table-row
、
table-row-group
、table-header-group
、table-footer-group
(分别是HTML
table
、row
、tbody
、thead
、tfoot
的默认属性)或inline-table
) overflow
值不为visible
的块元素display
值为flow-root
的元素contain
值为layout
、content
或strict
的元素- 弹性元素(
display
为flex
或inline-flex
元素的直接子元素) - 网格元素(
display
为grid
或inline-grid
元素的直接子元素) - 多列容器(元素的
column-count
或column-width
不为auto
,包括column-count
为 1) column-span
为all
的元素始终会创建一个新的BFC
,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug
)。
参考资料:
MDN