关于解决margin塌陷和合并问题

在标准的文档流中,竖直方向(注意:左右方向是不会出现塌陷的现象。)的margin会出现叠加现象,即较大的margin会覆盖掉较小的margin,竖直方向的两个盒子中间只有一个较大的margin,这就是margin的塌陷现象。

1. 什么是外边距合并

外边距合并就是:当两个垂直外边距相遇时,它们将形成一个外边距。合并的外边距的高度等于两个发生合并的外边距的高度中的较大者

2. 常见的几种情况

  1. 两个元素是父子关系,见如下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    <!DOCTYPE html>
    <html lang="zh">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    *{
    margin: 0;
    padding: 0;
    }
    .parent{
    margin-top: 20px;
    width: 100px;
    height: 100px;
    background: red;
    }
    .son{
    margin-top: 10px;
    width: 50px;
    height: 50px;
    background: gold;
    }
    </style>
    </head>
    <body>
    <div class="parent">
    <div class="son"></div>
    </div>
    </body>
    </html>

    得到如下图所示的内容,我们会发现黄色容器本应该距离上面的距离为30px,但是最后只距离上面20px:
    父子元素margin-top塌陷问题

  2. 两个元素是兄弟元素,见如下代码所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!DOCTYPE html>
    <html lang="zh">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    *{
    margin: 0;
    padding: 0;
    }
    .box1,
    .box2{
    width: 100px;
    height: 100px;
    background: red;
    }
    .box1{
    margin-bottom: 20px;
    }
    .box2{
    margin-top: 10px;
    }
    </style>
    </head>
    <body>
    <div class="box1"></div>
    <div class="box2"></div>
    </body>
    </html>

    得到如下图所示的内容,本应该是两个兄弟元素之间的距离为30px,但是实际它们之间的距离是20px:
    兄弟之间的margin塌陷问题

3. 相关的解决办法

  1. 父子关系的盒子解决办法:
    a. 给父盒子加一个边框;
    b. 给父元素添加上下的padding;
    c. 溢出隐藏,给父元素添加overflow:hidden;
    d. 给父元素添加浮动(注意:不推荐使用,因为会带来未知的错误);
    e. 给父元素添加position:fixed;
    f. 给父元素设置display:table;
    g. 给父元素设置伪元素(这是我们推荐的解决办法)。
    下面代码将上面所有的方法都举了一个例子来列举出来:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    <!DOCTYPE html>
    <html lang="zh">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    *{
    margin: 0;
    padding: 0;
    }
    .parent{
    margin-top: 20px;
    width: 100px;
    height: 100px;
    background: red;
    /* border: 1px solid black; 解决办法一 */
    /* padding-top: 10px; 解决办法二 */
    /* overflow: hidden; 解决办法三 */
    /* float: left; 解决办法四,但是不推荐使用 */
    /* position: fixed; 解决办法五*/
    /* display: table; 解决办法六*/
    }
    /* .parent::before{
    content: "";
    display: table;
    } 解决办法六,推荐使用*/
    .son{
    margin-top: 10px;
    width: 50px;
    height: 50px;
    background: gold;
    }
    </style>
    </head>
    <body>
    <div class="parent">
    <div class="son"></div>
    </div>
    </body>
    </html>
  2. 兄弟关系的解决办法:
    a. 给上面的盒子加个margin-bottom(这个距离等于两个盒子之间的距离)或者给下面的盒子加个margin-top(这个距离等于两个盒子之间的距离)。(推荐使用)
    b. 使用bfc来进行一个解决,关于bfc我在以前是写过的,在这里就不做相关介绍了,如果对bfc有疑惑的同学可以去网上搜索搜索。使用bfc解决:将兄弟元素分别作为子元素放在块级元素内,然后将其父级元素的渲染规则该为BFC。(不推荐使用)
    下面代码将上面所有的方法都举了一个例子来列举出来:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    <!DOCTYPE html>
    <html lang="zh">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    *{
    margin: 0;
    padding: 0;
    }
    .box1,
    .box2{
    width: 100px;
    height: 100px;
    background: red;
    }
    .box1{
    /* margin-bottom: 30px; 解决办法一:给该元素设置两个距离之和或者给box2设置两个元素之间的距离,即20+10=30px*/
    margin-bottom: 20px;
    }
    .box2{
    margin-top: 10px;
    }
    .parent{
    overflow: hidden; /* 触发bfc*/
    }
    </style>
    </head>
    <body>
    <!-- 在这里parent的容器是我们解决方法二所添加的容器 -->
    <div class="parent">
    <div class="box1"></div>
    </div>
    <div class="parent">
    <div class="box2"></div>
    </div>
    </body>
    </html>