10
头图

tip: In order to learn more intuitively, this article has omitted some css style codes.

I believe that the following situation is often encountered in daily work: in the production of static pages, for the overall coordination and beauty of the page, we want the upper edge of the image-div of the child box to be a certain distance from the upper edge of the header-div of the parent box spacing.

Current page effect:

Target page effect:

In order to achieve the effect of the above picture, we can first think of setting an upper margin for the child box:

<style>
    .image-div {    /*子盒子*/
        margin-top:25px;
    }
</style>

Let's see how it turns out?

The result is not the same as we expected. The image-div of the child box does not form a certain distance from the upper edge of the header-div of the parent box. The two boxes have moved down together, leaving an extra red frame area.

This phenomenon is one of the "margin collapse" problems often encountered in CSS.

Margin collapse

The top and bottom margins of the block-level elements in the stream sometimes merge (collapse) into a single margin (the largest margin after merging). This phenomenon is called margin collapsing (margin collapsing).

The reason for the margin collapse is the outer margin. There are four calculation situations:

  • If both are positive, take the maximum value
  • If they are the same, take one of them
  • If there are positives and negatives, take the largest positive number plus the smallest negative number
  • If they are all negative numbers, take the minimum value.

Collapse between adjacent (sibling) boxes

In CSS, the adjacent two sibling boxes is the common , which will cause the margin between adjacent sibling boxes to collapse.

The following figure is a related example, set the bottom margin of the div1 box, and set the top margin of the div2 box below:

<style>
    #block1 {
        margin-bottom: 20;
    }
    #block2 {
        margin-top: 10;
    }
</style>

<div id = "block1">div1</div>
<div id = "block2">div2</div>

First look at the margin area (red box) of div1 in the browser developer tools:

The margin area of div2 (green frame area):

Corresponding situation: If the margins between the two boxes are both positive, take the maximum value.

The following is example 2, we change the margin in example 1 to a negative number:

<style>
#block1 {
    margin-bottom: -20;
}
#block2 {
    margin-top: -10;
}
</style>

<div id = "block1">div1</div>
<div id = "block2">div2</div>

The overlapping distance of the two boxes is the smallest of the two negative numbers "-20px" (the absolute value is the largest |-20px|).

Solution

If you want to avoid this collapse, you can solve it in the following two ways:

  • Set margins for only one of the boxes
  • Set a parent box to the two boxes respectively, set the parent box property to overflow: hidden, and make the parent box a confined area, thereby triggering BFC

Collapse between father and son boxes

However, setting the parent box is not perfect. The margins will collapse when the following situations occur:

  • block elements the margin-top and its first subelement between margin-top there is no border, padding, inline content, clearance separated.
  • block element has no border, padding, inline content, height, min-height, max-height separation between the margin-bottom of the the last child element

At the same time, if the parent and child share a top margin area, for example, when the parent box has no top margin, the child box has a top margin. At this time, the child box moves down with the parent box (equivalent to setting a margin for the parent box) and the box collapses.


<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>

The parent element does not set the margin, the first child element is set margin: 30px, you will find that the parent element and the child element move down 30px together:

Solution

The core solution to this collapse is to separate the parent and child boxes. We can set the border or inner margin for the parent box, or add the overflow: hidden attribute to the parent box label. By triggering the BFC rule, that is, the block-level format context, the parent is rendered into an independent area to solve the problem between the parent and child boxes. The collapse problem.

BFC rule triggering method:

  • float is not none
  • overflow is not visible (usually overflow: hidden)
  • position is fixed, absolute
  • display is flex, inline-block, table-cell

Of course, when choosing a solution for the collapse, you should base on the specific situation. You cannot use the same solution for all situations, otherwise other problems will appear~

Then, after we learn the above knowledge, we can clearly know that the problem introduced at the beginning is the collapse between the parent-child box, and we can solve it by triggering the BFC rule (only one of the solutions):

<style>
    .image-div {    /*子盒子*/
        margin-top:25px;
    }
    .header-div {   /*父盒子*/
        overflow:hidden;    /*触发bfc*/
    }
<style>

The above are the common collapses and solutions for CSS box margins. I hope it can be helpful to you.

Recommended reading

Understand the browser storage and caching mechanism

Python Type Hints from entry to practice


云叔_又拍云
5.9k 声望4.6k 粉丝

又拍云是专注CDN、云存储、小程序开发方案、 短视频开发方案、DDoS高防等产品的国内知名企业级云服务商。