likes
comments
collection
share

复习|外边距折叠(塌陷)这事

作者站长头像
站长
· 阅读数 17

复习|外边距折叠(塌陷)这事

前言

要开始【复习】系列了,没办法的事,一些理论知识还是要的,知道归知道,会用归会用,但是那人问你你得条理清晰的回答出来。谁是那人???懂的都懂

关于 margin collapsing 翻译为外边距塌陷还是折叠这事,都有人提,我个人更倾向于折叠。折叠挺好理解啊,你有下外边距,我有上外边距,两边一靠近,重合折叠了。塌陷嘛,有一边塌了没了?

也不好说啥,只说个人倾向于叫“外边距折叠”,后文都成 margin collapsing 为外边距折叠。

什么是外边距折叠

块的上外边距(margin-top)和下外边距(margin-bottom)有时合并(折叠)为单个边距,其大小为单个边距的最大值(或如果它们相等,则仅为其中一个),这种行为称为外边距折叠

举个例子,两个相邻的 div 元素,上一个设定了距离底部的外边距是50px,下面的一个 div 设定的距离顶部的外边距是70px,而这两个相邻div实际上的外边距距离是70px,而不是50px。这就是发生了外边距折叠现象,有一边的外边距被折叠了。

下面是两个示意对比图

复习|外边距折叠(塌陷)这事

复习|外边距折叠(塌陷)这事

什么时候会发生外边距折叠

1.同一层级的两个相邻元素

普通的两个相邻块级元素,可以发生外边距折叠。后一个元素没使用clear 清除浮动。

例如下面这两个元素,会发生外边距折叠,它们实际的外边距距离是70px。

<style>
    div:nth-child(1){
        background: #1e87f0;
        margin-bottom: 50px;
    }

    div:nth-child(2){
        background: #42b983;
        margin-top: 70px;
    }
</style>
<div>上铺的兄弟</div>
<div>下铺的兄弟</div>

2.直接相邻的父子元素

下面是一段来自 mozilla 的翻译解释,可以看得出来,父子元素发生外边距折叠的条件是复杂的。

如果没有边框border,内边距padding,行内内容,也没有创建块级格式上下文或清除浮动来分开一个块级元素的上边界margin-top 与其内一个或多个后代块级元素的上边界margin-top;或没有边框,内边距,行内内容,高度height,最小高度min-height或 最大高度max-height 来分开一个块级元素的下边界margin-bottom与其内的一个或多个后代后代块元素的下边界margin-bottom,则就会出现父块元素和其内后代块元素外边界重叠,重叠部分最终会溢出到父级块元素外面

下面是一个父元素和其子元素发生 margin-top 折叠的情形,实际的外边距距离不是两者 margin-top 的和,而是取了一个较大的值 70px。

复习|外边距折叠(塌陷)这事

复习|外边距折叠(塌陷)这事

<style>
    body{
        margin: 0;
    }
    .parent-box {
        background: #1e87f0;
        margin-top: 40px;
    }

    .parent-box > div {
        margin-top: 70px;
        background: #42b983;
    }
</style>
<div class="parent-box">
    <div>子元素div</div>
</div>

类似的父子元素的场景,margin-bottom 也会发生外边距折叠。如下所示,父元素和其子元素的 margin-bottom 发生了折叠,实际的外边距距离取了大的值 70px。

复习|外边距折叠(塌陷)这事

<style>
    body{
        margin: 0;
    }
    .parent-box {
        background: #1e87f0;
        margin-bottom: 40px;
    }

    .parent-box > div {
        margin-bottom: 70px;
        background: #42b983;
    }
</style>
<div class="parent-box">
    <div>子元素div</div>
</div>
<div style="background: red">父元素的兄弟元素</div>
</body>

3.空的块级元素

当一个块元素上边界margin-top 直接贴到元素下边界margin-bottom时也会发生边界折叠。这种情况会发生在一个块元素完全没有设定边框border、内边距padding、高度height、最小高度min-height 、最大高度max-height 、内容设定为inline或是加上clear-fix的时候。

如下所示,是一个空元素发生外边距折叠的示例,原本位于第二行的空元素设置了距离上边元素100px,距离下边元素150px,如果不发生折叠,第一行和第三行元素应该是距离 100 + 0(第二行元素为空高度为0)+ 150=200px,然而实际上是150px。这就是说这个空元素自身的margin 发生了折叠,只取了大的值150px,另外的100px被折叠且溢出到了第三行元素。

复习|外边距折叠(塌陷)这事

<style>
    div:nth-child(2) {
        background: #f01e4f;
        margin-bottom: 150px;
        margin-top: 100px;
    }
</style>
<div style="background: #42b983">第一行元素</div>
<div></div>
<div style="background: #1e87f0">第三行元素</div>

不会发生外边距折叠的条件

1.不会发生的条件

①行内块元素 inline-block 不会发生外边距折叠,包括同层级和嵌套元素。

②浮动 float 元素不会发生外边距折叠,包括同层级和嵌套元素。

③绝对定位元素 absolute 不会发生外边距折叠,包括同层级和嵌套元素。

④创建了 BFC 的元素不会和它的子元素发生外边距折叠。

2.注意事项

①折叠现象发生在块级元素,且是top 和 bottom 的外边距,因此与行内元素无关,再说行内元素上下外边距天然就不会生效,如果当做生效,那么行内元素只要有top 和 bottom 天然就会折叠。

②外边距折叠,可能会产生子元素溢出父元素的现象,不论父元素外边距是否为 0。

③当相邻元素和嵌套元素都发生外边距折叠,那么情况将更复杂。

④折叠让他折叠,设置外边距在两个靠近的元素中,只设置一边的 top 或 bottom,这可能是个好习惯。

外边距折叠的计算小结

尽管说我们应该努力的方向是尽量避免产生外边距折叠,而不是去结算折叠后的值,一旦产生折叠现象,我就改代码,让他不产生折叠,而不是产生之后去计算折叠的值。

但是既然学到了这,还是看看折叠后的值,通常是咋算的:

1.同正或同负:选绝对值最大的。

比如 -50px 和 -70px 发生折叠,那么折叠后的值是 70px,因为 -70 的绝对值最大嘛,要是 -50px 和 -50px,当然此时绝对值最大也是 50px 嘛,所以你只有一个选择 50px。

比如 50px 和 70px 发生折叠,那么折叠后的值是 70px,因为 70 的绝对值最大嘛,要是 50px 和 50px,当然也选绝对值最大的 50px。

2.有正有负:最大的正边距与最小的负边距的和。

例如 70px、-50px、20px 发生折叠,那么边界范围就是 70px + (-50px)= 20px。