Topic of this paper:

  • Basic concept: Standard model + IE model
  • The difference between the basic model and IE model: calculate the difference in width and height
  • How CSS sets up these two models (from theory to application)
  • How does JS set and obtain the width and height of the box model
  • The extension of the height of the real example (to explain the margin overlap problem according to the box model)
  • BFC (Margin Overlap Solution) is a common and confusing interview question

The box model

The basic concept

What is the CSS box model? I believe that most people can answer this question, that is the standard model + IE model

Standard model:

IE model

obviously

  • In the standard box model,widthheightThis refers to the width and height of the content area. Increasing margins, borders, and margins does not affect the size of the content area, but does increase the overall size of the element box.
  • In the IE box model,widthheightRefers to thecontent+border+padding

How does CSS set up these two models

  • Standard model:box-sizing: content-box;
  • IE model:box-sizing: border-box;

How does JS set the width and height of the box model

  • dom.style.width/height: Can only fetch the width and height of the inline style<div id="aa" style="width: 200px"></div>
  • dom.currentStyle.width/heightGet the real-time computing style, but only IE supports it. To support other browsers, you can do this
  • window.getComputedStyle(dom).width: Better compatibility
  • dom.getBoundingClientRect().width/height: This is used less often, mainly to calculate the absolute position in the page

Margins overlapping

What is margin overlap?

Boundary overlap is when the adjacent boundaries of two or more boxes (which may be adjacent or nested) (without any non-empty content, padding, or borders between them) overlap to form a single boundary.

The boundaries of the parent and child elements overlap

<style>
  .parent {
    background: #e7a1c5;
  }
  .parent .child {
    background: #c8cdf5;
    height: 100px;
    margin-top: 10px;
  }
</style>
<section class="parent">
  <article class="child"></article>
</section>
Copy the code

The desired effect:

In practice, the effect is as follows:

Here the parent element is not 110px high, but 100px high, and there is a height collapse.

The reason is that if a block element’s margin-top is not separated from its first child’s margin-top by border, padding, inline Content, and clearance, Or there is no border, padding, inline content, height, min-height, max-height between the margin-bottom of a block element and the margin-bottom of its last child element. So the margins are going to collapse. Excess margins of child elements are truncated by margins of parent elements.

The boundaries of sibling elements overlap

<style>
  #margin {
    background: #e7a1c5;
    overflow: hidden;
    width: 300px;
  }
  #margin > p {
    background: #c8cdf5;
    margin: 20px auto 30px;
  }
</style>
<section id="margin">
  <p>1</p>
  <p>2</p>
  <p>3</p>
</section>
Copy the code

You can see that the spacing between 1 and 2 is not 50px, the spacing between 2 and 3 is overlapped by taking the maximum of 30px between them.

The boundaries of empty elements overlap

Suppose you have an empty element that has a margin, but no border or padding. In this case, the upper and lower margins touch each other, and they merge:

BFC

One way to solve these problems is to create BFC. The full name of BFC is Block Formatting Context.

  • The elements in the same BFC influence each other, and margin collapse may occur.
  • The BFC is a separate container on the page, and the child elements inside the container do not affect the outside elements and vice versa;
  • When calculating the height of the BFC, all elements contained in the BFC, including floating elements, are considered.
  • [Fixed] The floating box area is not superimposed on the BFC

Prevent vertical margin overlap

The solution to overlapping parent element boundaries is to add overflow:hidden on the parent element; Make it BFC.

.parent {
  background: #e7a1c5;
  overflow: hidden;
}
Copy the code

The boundary of the sibling element overlaps, creating a BFC context in the second child element:

<section id="margin"> <p>1</p> <div style="overflow:hidden;" > <p>2</p> </div> <p>3</p> </section>Copy the code

Clear internal float

<style>
  #float {
    background: #fec68b;
  }
  #float .float {
    float: left;
  }
</style>
<section id="float">
  <div class="float">I'm a floating element</div>
</section>
Copy the code

The height of the parent element #float is 0. The solution is to create a BFC for the parent element #float, so that the height of the floating child element also participates in the height calculation of the parent element:

#float {
  background: #fec68b;
  overflow: hidden; Float :left*/
}
Copy the code

Adaptive two-column layout

<section id="layout">
  <style>
    #layout {
      background: red;
    }
    #layout .left {
      float: left;
      width: 100px;
      height: 100px;
      background: pink;
    }
    #layout .right {
      height: 110px;
      background: #ccc;
    }
  </style>
  <! -- Left width fixed, right adaptive -->
  <div class="left">On the left</div>
  <div class="right">right</div>
</section>
Copy the code

Set the height of the right side to be higher than the left side, and you can see that the excess left side goes to the right. This is because the block box in the normal flow of the document behaves as if the float box does not exist because the float box is not in the normal flow of the document.

The solution is to create a BFC for the right-hand element, with the principle that the BFC does not overlap with the float element.

#layout .right {
  height: 110px;
  background: #ccc;
  overflow: auto;
}
Copy the code

Reference margin overlap with BFC