margin 塌陷及合并问题

margin塌陷问题:

父子关系结合的两个元素,在垂直方向上margin会粘合在一起,外层盒模型的margin-top取两个元素中margin-top较大的值。

正常的情况下内层元素是相对于外层元素进行移动,发生margin塌陷时内层元素却相对于整个文档进行移动。


margin塌陷问题例子演示如下:设置一个父元素div套一个子元素div
(父元素边框100px 子元素边框50px)

/*CSS代码*/
.father{
    width: 100px;
    height: 100px;
    background-color: #FFE43E;
}
.son{
    width: 50px;
    height: 50px;
    background-color:  #AEDAFF;
}
<!--HTML代码-->
<div class="father">
    <div class="son"></div>
</div>

*注:虚线位置为原图位置

  • 我们先看一组正常情况(水平方向):
    (Ⅰ.) 我们给父元素设置margin-left: 50px;父元素相对于原位置携带其子元素向右移动50px;如(图1)

    (Ⅱ.) 我们在父元素设置margin-left: 50px;的基础上,设置子元素margin-left: 50px;和我们所想的一样此时子元素是相对于父元素移动的,向右移动了50px;如(图2)
    同样设置margin-left: 100px;子元素是相对于父元素右移动了100px;移出到父元素外面。如(图3)
    这里写图片描述这里写图片描述这里写图片描述
    正常的情况下内层元素是相对于外层元素进行移动


  • margin塌陷的情况(垂直方向):

(Ⅰ.) 如果我们给父元素设置margin-top: 50px;,如(图1)父元素会带着他的儿子 一起向下移动50px;这和我们所想的一样。

可是如果我们再设置子元素 margin-top: 50px;,我们所想是子元素会相对于原位置
移动到据父元素顶部向下50px的位置,(也就是父元素的左下角位置),可实际上它仍是(图1)所示的位置.(它并没有相对于父元素移动!)

(Ⅱ.) 我们再次测试,在父元素设置margin-top: 50px;的基础上,设置子元素margin-top: 60px;奇迹出现了,子元素带着它爸一起向下移动了10px;如(图2)
同样我们在父元素设置margin-top: 50px;的基础上,设置子元素margin-top: 100px;
子元素与父元素一同移动了100px;如(图3)
这里写图片描述这里写图片描述这里写图片描述
这就是我们所说的margin塌陷 出现margin塌陷时内层元素却相对于整个文档进行移动,好像外层元素没有“棚顶”一样
结论:
父子关系盒子嵌套中父元素设置margin-top 父会携带子元素移动相应的距离。
子元素设置margin-top 时如果该值未超出父元素所设置的margin-top值 则不移动。若超出,则子元素携带父元素相对于整个文档 移动到相应的margin-top位置。
即:外层盒模型的margin-top取两个元素中margin-top较大的值。


下来问题来了,如何解决这种浏览器内核所造成的问题呢?

解决方法:

(Ⅰ.)改变父级元素渲染规则,使其变为BFC元素。

这里简单说一下如何触发一个盒子的BFC:

position: absolute;
display: inline-block;
float: left/right;
overflow: hidden;

解决方法:结果如(图4.)

.father{
    width: 100px;
    height: 100px;
    background-color: #FFE43E;
    margin-top: 50px;
    display: inline-block;/*使其变为行级块元素*/
}
.son{
    width: 50px;
    height: 50px;
    background-color:  #AEDAFF;
    margin-top: 50px;
}

这里写图片描述
(Ⅱ.)给外层元素加一个顶棚 border (给父元素设置边框)

    border-top: 1px solid transparent;/*可以加上框顶部*/
    border: 1px solid transparent; /*可以加上整个边框*/
.father{
    width: 100px;
    height: 100px;
    background-color: #FFE43E;
    border: 1px solid transparent;/*加上一个边框*/
    margin-top: 50px;
}
.son{
    width: 50px;
    height: 50px;
    background-color:  #AEDAFF;
    margin-top: 50px;
}

如(图5)这是为加边框前所显示的样子 。(图6)加上边框后显示的样子,对比两张图虚线部分,认真观察盒子的大小(右边框处)有细微的变化。
(所以 这种方法虽然能够解决问题,但是在日常开发中我们不使用它,因为它在外观上对元素做了修改。)
这里写图片描述这里写图片描述


讨论完margin塌陷,我们来说一下margin合并,理解了上面那个这个也就简单了。
和margin塌陷一样。

margin合并:

margin合并是相对于兄弟关系的div来说的。
处于上下位置关系(竖直方向)的两个div容器,在通过margin-top、margin-bottom改变间距时,其外边距会产生重叠现象,两者相隔的外边距取的是两者所设置margin的最大值。

/*CSS代码*/
.one{
    width: 100px;
    height: 50px;
    background-color:#fff896;
}
.two{
    width: 100px;
    height: 50px;
    background-color:#6bff94;
}
<!--HTML代码-->
    <div class="one"></div>
    <div class="two"></div>

(Ⅰ.)设置两个兄弟元素他们的相对位置如(图1),给上面的one 设置 margin-bottom: 50px;后,两元素相距50px 如(图2.)

我们再在one设置margin-bottom: 50px;的基础上设置two 的margin-top: 50px;,两者距离仍为50px 如(图1)

(Ⅱ.)当我们在one设置margin-bottom: 50px;的基础上设置two 的margin-top: 100px;时,两者的距离才发生了改变,达到我们想要的效果(相聚100px)如(图3)
这里写图片描述这里写图片描述这里写图片描述


这就是我们所说的margin合并问题。他的解决方法和前者类似。

解决margin合并:

(Ⅰ.)可以将其中一个元素包起来,在外层元素中设置bfc渲染规则。此时这个元素的渲染规则就改变了,这样就可以达到想要的效果了。

.three{
    overflow: hidden;/*触发BFC*/
}
.one{
    width: 100px;
    height: 50px;
    background-color:#fff896;
    margin-bottom: 50px;
}

.two{
    width: 100px;
    height: 50px;
    background-color:#6bff94;
    margin-top: 50px;
}

<div class="three">
    <div class="one"></div>
</div>
    <div class="two"></div>

不过 解决margin合并 要同时改变HTML和CSS。 所以一般不提倡上述这种方法(一般要避免在结构上引入多余的HTML)。
margin合并可以通过计算处理掉。

猜你喜欢

转载自blog.csdn.net/qq_41853863/article/details/80791755