This is the fifth day of my participation in the November Gwen Challenge. Check out the details: The last Gwen Challenge 2021

The purpose of this series of interview questions is to learn the relevant knowledge so that you can easily solve the various forms of exam questions. This article covers BFC and how to solve the margin overlap problem with BFC.

Block-level Formatting Context (BFC)

Block Formatting Context (BFC)

What is landing

The BFC is a separate region, its internal elements are rendered according to its rules and do not interact with the outside of the BFC.

BFC layout rules

  • The inner boxes will be placed vertically, one by one;
  • The vertical distance of the box is determined bymarginDecide, belong to the sameBFCAbove and below the two adjacent boxesmarginThere will be overlap;
  • The left side of each element touches the left side of the containing block (and vice versa for right-to-left layouts), even if there is a float;
  • BFCThe area will not be withfloatOverlapping;
  • BFCIt is a separate container on the page, and the child elements inside the container do not affect the outside elements. And vice versa;
  • To calculateBFCWhen the float element is also involved in the calculation.
  • When an element is set to newBFCAfter, and the outside of this elementBFCIt doesn’t matter, this element is only going to constrain its own child elements.

The following method creates a BFC

  • overflow: not forvisible;
  • float: not fornone;
  • display: in order toinline-block,table,table-cell,table-caption,flex,inline-flex,grid,inline-grid,flow-root;
  • position: in order toabsoluteorfixed;

It can be simply known as OFDP. When the interviewer asks you, if you answer “OFDP”, the interviewer will probably know that you understand this knowledge point.

Margins overlap between parent and child elements

Scenario 1: Look at this code first. The expected result is that the parent should be 100px away from the top of the page and the children 100px away from the parent.

 <style>
  body {
    background: gray;
    margin: 0;
    padding: 0;
  }
  .container {
    width: 600px;
    height: 600px;
    background: yellow;
    margin-top: 100px;
  }
  .content {
    width: 200px;
    height: 200px;
    background: green;
    margin-top: 100px;
  }
</style>
<body>
    <div class="container">
      <div class="content"></div>
    </div>
</body>
Copy the code

Instead, we get the result that the parent is 100px away from the top of the page, but there is no distance between the child and the parent.

Scenario 2: Looking at this code again, the expected result is that the parent container is close to the top of the page and the child container is 100px away from the parent.

 <style>
  body {
    background: gray;
    margin: 0;
    padding: 0;
  }
  .container {
    width: 600px;
    height: 600px;
    background: yellow;
  }
  .content {
    width: 200px;
    height: 200px;
    background: green;
    margin-top: 100px;
  }
</style>
<body>
    <div class="container">
      <div class="content"></div>
    </div>
</body>
Copy the code

The result is the same. There is no distance between the child and the parent, but the parent is separated from the top of the page. How can this happen?

Phenomenon: Margin overlap occurs, where the margins of a box and its descendants overlap.

Rule: positive and negative take the largest, negative and negative take the most negative, plus and minus add up.

Reason: According to the specification, the top margin of a box without BFC should overlap the top margin of the first child element in its document flow.

Solution: Make it BFC by adding overflow: Hidden property to the parent container.

 .container {
     overflow: hidden;
  }
Copy the code

This is what we want.

How it works: THE BFC is an independent container on the page and does not affect the parent/external/internal.

Sibling element margins merge

Scenario 3: Look at this code again. Two sibling elements, one with a bottom margin of 100px and the other with a top margin of 100px, are expected to be 200px apart.

<style>
  body {
    background: gray;
    margin: 0;
    padding: 0;
  }
  .container {
    width: 600px;
    height: 600px;
    background: yellow;
  }
  .box1 {
    width: 200px;
    height: 200px;
    background: green;
    margin-bottom: 100px;
  }
  .box2 {
    width: 200px;
    height: 200px;
    background: blue;
    margin-top: 100px;
  }
</style>
<body>
    <div class="container">
        <div class="box1"></div>
        <div class="box2"></div>
    </div>
</body>
Copy the code

But the distance between the two sibling elements is only 100px.

Appearance: Margin overlap occurs, and the top and bottom margins of two sibling elements overlap.

Rule: positive and negative take the largest, negative and negative take the most negative, plus and minus add up.

Reason: The upper or lower margins of block-level elements are sometimes combined into a single margin (when directly touching/adjacent).

Solution: Make one of the sibling elements BFC by adding the parent container and the Overflow: Hidden property.

<style>
  body {
    background: gray;
    margin: 0;
    padding: 0;
  }
  .container {
    width: 600px;
    height: 600px;
    background: yellow;
  }
  .father {
    overflow: hidden;
  }
  .box1 {
    width: 200px;
    height: 200px;
    background: green;
    margin-bottom: 100px;
  }
  .box2 {
    width: 200px;
    height: 200px;
    background: blue;
    margin-top: 100px;
  }
</style>
<body>
    <div class="container">
      <div class="father">
        <div class="box1"></div>
      </div>
      <div class="box2"></div>
    </div>
</body>
Copy the code

This is what we want.

Principle: Vertical margins of elements belonging to different BFC do not overlap.

Empty element margin merge

Scene 4: There are four empty elements between two sibling elements, each with a 25px margin-top, and the expected result is that the two sibling elements are 100px apart.

<style>
  body {
    background: gray;
    margin: 0;
    padding: 0;
  }
  .container {
    width: 600px;
    height: 600px;
    background: yellow;
  }
  .box1 {
    width: 200px;
    height: 200px;
    background: green;
  }
  .box2 {
    width: 200px;
    height: 200px;
    background: blue;
  }
  .null {
    margin-top: 25px;
  }
</style>
<body>
    <div class="container">
      <div class="box1"></div>
      <p class="null"></p>
      <p class="null"></p>
      <p class="null"></p>
      <p class="null"></p>
      <div class="box2"></div>
    </div>
</body>
Copy the code

But it turns out that there is only one empty element distance, which is 25px.

Phenomenon: Margin overlap occurs, where the margins of all empty elements overlap into the margins of an empty element.

Margin merges occur if a block-level element has no content and margin-top and margin-bottom are set.

Solution: Add a parent to each container and add overflow: Hidden property to make it BFC.

<style>
  body {
    background: gray;
    margin: 0;
    padding: 0;
  }
  .container {
    width: 600px;
    height: 600px;
    background: yellow;
  }
  .box1 {
    width: 200px;
    height: 200px;
    background: green;
  }
  .box2 {
    width: 200px;
    height: 200px;
    background: blue;
  }
  .null {
    margin-top: 25px;
  }
  .father {
    overflow: hidden;
  }
</style>
<body>
    <div class="container">
      <div class="box1"></div>
      <div class="father">
        <p class="null"></p>
      </div>
      <div class="father">
        <p class="null"></p>
      </div>
      <div class="father">
        <p class="null"></p>
      </div>
      <div class="father">
        <p class="null"></p>
      </div>
      <div class="box2"></div>
    </div>
</body>
Copy the code

That’s what we’re trying to do. However, there are few practical application scenarios for this kind of situation.

Principle: Vertical margins of elements belonging to different BFC do not overlap.

Feel helpful small partners please click 👍 support, thank you ~