A landing.

1.1 define

Bfc-block Formating Context

  • The internal boxes will be placed one after the other vertically
  • The margins of two adjacent boxes of the same BFC will overlap
  • When calculating the height of the BFC, the floating child element also participates in the calculation
  • The region of the BFC does not overlap with the float box.
  • The BFC is a completely independent space, so that the child elements in the space do not affect the layout of the outside

When a float exists outside the BFC, it should not affect the layout of the Box inside the BFC, and the BFC does not overlap the float by narrowing (if the width is not set)

When there is a float inside the BFC, the BFC calculates the height of the float so as not to affect the layout of external elements. The same goes for avoiding margin overlap.

1.2 Trigger Principle

body

float:left/right

position:fixed/absolute

display:inline-block/table-cell/fixed

Overfolw visible

1.3 Problems solved by BFC

1.3.1 Margin merging problem

 <div class="box1"></div>
 <div class="box2"></div>
Copy the code
 div{
        width:100px;
        height:100px;
      }
      .box1{
        background-color: red;
        border:1px solid blue;
        padding:10px;
        margin-bottom:30px;
      }
      .box2{
        background-color: green;
        border:1px solid blue;
        padding:10px;
        margin-top:20px;
      }
Copy the code

The vertical margin values of two adjacent boxes appear to be merged into the value with the larger margin, and the use of border or padding cannot prevent this phenomenon.

Reason: The vertical distance of Box is determined by margin. Margins of two adjacent boxes belonging to the same BFC(in this case, the BFC of the body root element) will overlap

 <div class="container">
      <div class="box1"></div>
    </div>
    <div class="box2"></div>
Copy the code
 .box1{
        background-color: red;
        margin-bottom:130px;
        width:100px;
        height:100px;
      }
      .box2{
        background-color: green;
        margin-top:120px;
        width:100px;
        height:100px;
      }
      .container{
        overflow: hidden;
      }
Copy the code

The solution is to make box1 a child of the new BFC element. Container a child of the body BFC element. Box2 is in a different BFC, so margin merges

 <div class="container">
      <div class="box1"></div>
    </div>
Copy the code
.box1{
    background-color: red;
    margin-top:150px;
    width:100px;
    height:100px;
  }
  .container{
    width:200px;
    height:200px;
    margin-top:100px;
    background-color: green;
  }
Copy the code

When the parent element has a margin value and the child element also has a margin value, take the maximum value of the two to merge, and there is another question is why the margin of the child element is not relative to the parent element, which involves the problem of margin-top collapse

This is because both the parent box and the child box are in the body BFC. The three boxes belong to the same BFC, so the body also has margins at the beginning, so it will merge with the parent box’s 100 first, and then merge with the child box to form the final 150px.

.box1{
    background-color: red;
    margin-top:150px;
    width:100px;
    height:100px;
  }
  .container{
    width:200px;
    height:200px;
    margin-top:100px;
    background-color: green;
    overflow: hidden;
  }
  body{
    display: flex;
  }
Copy the code

Let the parent box form a new BFC, then the BFC element is not the same as the body element, then the margin will not merge, so it will be 108px. Second, the element that creates the BFC does not add margins to its children.

1.3.2 Margin-top collapse problem

<div class="container">
      <div class="box"></div>
</div>
Copy the code
.container{
      width:500px;
      height:500px;
      background-color: blue;
      padding-top:10px;
      /* border:1px solid red; * /
    }
    .box{
      width:100px;
      height:100px;
      background-color: green;
      margin-top:50px;
    }
Copy the code

When the parent box has the border-top or padding-top attribute, the child box is not adjacent to the parent box, so the margin-top collapse problem will not occur

<div class="container">
      <div class="box"></div>
</div>
Copy the code
.container{
      width:500px;
      height:500px;
      background-color: blue;
    }
    .box{
      width:100px;
      height:100px;
      background-color: green;
      margin-top:50px;
    }
Copy the code

In this case, marin-top collapse occurs, which means that the child element sets a margin-top value but it does not shift relative to the parent box, but moves with the parent box to the previous outer element

<div class="container">
      <div class="box"></div>
</div>
Copy the code
.container{
      width:500px;
      height:500px;
      /* overflow:hidden; * /
      /* position: absolute; * /
      position:fixed;
      background-color: blue;
    }
    .box{
      width:100px;
      height:100px;
      background-color: green;
      margin-top:50px;
    }
Copy the code

Trigger the BFC of the parent box to solve this problem

1.3.3 Height collapse problem (Float induced height collapse problem)

 <div class="box">
      <div class="box1"></div>
      <div class="box2"></div>
    </div>
Copy the code
 .box{
      width:200px;
      border:2px solid red;
    }
    .box1{
      float:left;
      width: 100px;
      height:100px;
      background-color: orange;
    }
    .box2{
      float:left;
      width: 100px;
      height:100px;
      background-color: green;
    }
Copy the code

 .box{
      width:200px;
      border:2px solid red;
      /* float:left ; * /
      overflow:hidden;
    }
    .box1{
      float:left;
      width: 100px;
      height:100px;
      background-color: orange;
    }
    .box2{
      float:left;
      width: 100px;
      height:100px;
      background-color: green;
    }
Copy the code

When the BFC is triggered to satisfy the height of the calculated BFC in the BFC rule, the floating element also participates in the calculation

1.3.4 Surround Issues (Float surround issues)

 <div class="box"></div>
  <div class="box1">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Praesentium cupiditate veniam ratione dicta eaque dolore ullam, minima at, maiores veritatis expedita repudiandae rem modi odit ab molestias, eveniet magni qui!</div>
Copy the code
 .box{
      width:100px;
      height: 100px;
      float:left;
      background-color: # 000;
    }
    .box1{
      /* float: left; * /
      width:200px;
      height:200px;
      background-color: orange;
    }
Copy the code

Because the first element floats out of the document flow, the second block-level element does not recognize the location of the floating element and is overwritten.

.box{
      width:100px;
      height: 100px;
      float:left;
      background-color: # 000;
    }
    .box1{
      float: left;
      width:200px;
      height:200px;
      background-color: orange;
    }
Copy the code

Triggering the BFC According to the BFC rules, the area of the BFC does not overlap with the float box to prevent overwriting

Reference documentation

Github.com/zuopf769/no…

2. The floating

2.1 the floating

Float was originally designed to wrap text around, but it destroys the normal document flow without overwriting the previous document flow. After all, floating elements do not affect previously laid elements, only subsequent elements.

<div class="container">
   <div class="box1"></div>
</div>
<div class="content">wenzi</div>
Copy the code
 .container{
      width:200px;
      border:1px solid red;
    }
    .box1{
      width:100px;
      height:100px;
      background-color: green;
      float: left;
    }
    .content{
      width:200px;
      height:200px;
      background-color: blue;
    }
Copy the code

Floating elements do not overwrite text

Floating impact:

It first causes the height of the parent element to collapse

Secondly, the layout of subsequent elements is affected by the high collapse

2.2 Clearing floats

2.2.1 Trigger BFC(BFC does not overlap with Float Box)

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="" />
  </head>
  <style type="text/css">

    .box{
      width:200px;
      border:10px solid # 000;
      overflow:hidden; 
      /* Clear the float but what if you need a scrollbar or something so this method is also bad */
    }
    .box1{
      float: left;
      width:100px;
      height:100px;
      background-color: green;
    }
    .box2{
      float: left;
      width:100px;
      height:100px;
      background-color: orange;
    }
  </style>
  <body>  
    <div class="box">
      <div class="box1"></div>
      <div class="box2"></div>
    </div>
  </body>
</html>
Copy the code

2.2.2 the clear: both

    /* The best way to clear the float */
    ul::after.div::after{
      content: "";
      display:block;
      clear:both;
    }
Copy the code

2.2.3 Setting to clear floating classes

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="" />
  </head>
  <style type="text/css">
    .box{
      width:200px;
      border:10px solid # 000;
    }
    .box1{
      float: left;
      width:100px;
      height:100px;
      background-color: green;
    }
    .box2{
      float: left;
      width:100px;
      height:100px;
      background-color: orange;
    }
    /* Remove floating defective methods */
    .fixclear{
      clear:both
    }
  </style>
  <body>  
    <div class="box">
      <div class="box1"></div>
      <div class="box2"></div>
      <p class='fixclear'></p>
    </div>
  </body>
  <script src="" type="text/javascript" charset="utf-8"></script>
</html>
Copy the code

Three. Absolute positioning

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="" />
  </head>
  <style type="text/css">
    .container{
      width:200px;
      border:1px solid red;
    }
    .box1{
      width:100px;
      height:100px;
      background-color: green;
      position:absolute;
    }
    .content{
      width:200px;
      height:200px;
      background-color: blue;
    }
  
  </style>
  <body>
    <div class="container">
      <div class="box1"></div>
    </div>
    <div class="content">wenzi</div>
  </body>
  <script src="" type="text/javascript" charset="utf-8"></script>
</html>
Copy the code

Absolutely positioned elements are overridden.

Four. Three column layout

4.1 the flex implementation

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="" />
  </head>
  <style type="text/css">
    #header.#footer{
    height: 50px;
    width: 100%;
    border: 1px solid;
    background-color: grey;
  }
  #content{
    display: flex;
    height:500px;
  }
  #left.#right{
    flex-basis: 200px;
    background-color: green;
  }
  #left{
    order:1
  }
  #middle{
    background-color: blue;
    flex-grow:1;
    order:2;
  }
  #right{
    order:3;
  }
  </style>
  <body>
    <div class="wrap">
      <div id="header">header</div>
      <div id="content">
        <div id="middle">middle</div>
        <div id="left">left</div>
        <div id="right">right</div>
      </div>
      <div id="footer">footer</div>
    </div>
  </body>
  <script src="" type="text/javascript" charset="utf-8"></script>
</html>
Copy the code

4.2 Grail Layout (using padding)

Problems to be solved:

  • Margin-left :-100%
  • Why positioning is needed
<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="" />
  </head>
  <style type="text/css">
#header.#footer{
    height: 50px;
    width: 100%;
    border: 1px solid;
    background-color: grey;
}
#content{ 
  overflow: hidden;
  padding: 0px 200px;/* To make the text visible */
}
#left.#right{
  width: 200px;
  height: 200px;
  background-color:pink;
}
#middle{
  background-color: green;
  width: 100%;/* Relative to 100% of the content */
  height: 200px;
  
}
#middle.#left.#right{
  float: left;

}
#left{
  / * here how to understand the margin - relative to the left border of the left is itself an element of the right boundary displacement * /
  margin-left: -100%;
  /* When the padding value is added, the margin-left is shifted relative to the content boundary, so the margin will change after the padding value is added
  position: relative;
  left: -200px;
}
#right{
  margin-left: -200px;
  position: relative;
  left: 200px;
}

  
  </style>
  <body>
    <div class="wrap">
      <div id="header">header</div>
      <div id="content">
        <div id="middle">middle</div>
        <div id="left">left</div>
        <div id="right">right</div>
      </div>
      <div id="footer">footer</div>
    </div>
    
  </body>
  <script src="" type="text/javascript" charset="utf-8"></script>
</html>
Copy the code

4.3 Dual-wing Layout (using margin)

<! DOCTYPEhtml>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
        <title>Document</title>
        <link rel="stylesheet" type="text/css" href="" />
    </head>
    <style type="text/css">
#header.#footer{
    height: 50px;
    width: 100%;
    border: 1px solid;
    background-color: grey;
}
#left.#right{
  width: 200px;
  height: 200px;
  background-color:pink;
}
#middle{
  background-color: green;
  width: 100%;
  height:200px;
  float: left;
}
#content{
  overflow: hidden;
}
#left{
  float: left;
  margin-left: -100%;
  /* When margin-left is -100% of the parent element, it moves a line. When the box is placed, it will be placed according to the margin (actually, it should be the left margin from the last sibling element) */

  /* Relative to the last floating box */
  /* here the margin is full */
}
#right{
  float: left;
  margin-left: -200px;  
  /* Left box margin */
}
.middle-inner{
  margin: 0 200px;  
  /* Since the middle content is now covered by the left and right, we can use the padding of the outer content as well as the margin of the middle; * /
}

    
    </style>
    <body>
        <div class="wrap">
            <div id="header">header</div>
            <div id="content">
              <div id="middle">
                <div class="middle-inner">middle</div>
              </div>
              <div id="left">left</div>
              <div id="right">right</div>
            </div>
            <div id="footer">footer</div>
          </div>
        
    </body>
    <script src="" type="text/javascript" charset="utf-8"></script>
</html>
Copy the code

5. Scaling rules involved in Flex layout

5.1 the flex – the shrink

5.1.1 only width

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="" />
  </head>
  <style type="text/css">
    * {
	padding: 0;
	margin: 0;
}
.container {
	width: 600px;
	height: 300px;
	display: flex;
}
.left {
	width: 500px;
	flex-shrink: 2;
	background: red;
}
.right {
	width: 400px;
	flex-shrink: 1;
	background: blue;
}

  </style>
  <body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
    </div>
  </body>
  <script src="" type="text/javascript" charset="utf-8"></script>
</html>
Copy the code

The width of.left and.right is obviously greater than 600, so what is the actual width of the two after flex-shrink is set?

  • Excess :500+400-600=300
  • Proportion: 5002:4001 = 5:2
  • Each block exceeds content: 3005/7 3002/7
  • .left Actual content: 500-300 *5/7 = 285.719
  • 500-300 *2/7 = 314.281

5.1.2 width + padding

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="" />
  </head>
  <style type="text/css">
   * {
	padding: 0;
	margin: 0;
}
.container {
	width: 600px;
	height: 300px;
	display: flex;
}
.left {
	width: 500px;
	flex-shrink: 2;
  padding:60px;
	background: red;
}
.right {
	width: 400px;
  padding:40px;
	flex-shrink: 1;
	background: blue;
}
  </style>
  <body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
    </div>
  </body>
  <script src="" type="text/javascript" charset="utf-8"></script>
</html>
Copy the code
  • Excess :620+480-600 = 500
  • Proportion: 5002:4001 = 5:2
  • Each block exceeds content: 5005/7 5002/7
  • . Left Actual content: 620-500 *5/7 = 262.857
  • Right actual content: 480-500 *2/7 = 337.143

5.1.3 width + padding + border

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="" />
  </head>
  <style type="text/css">
    * {
	padding: 0;
	margin: 0;
}
.container {
	width: 600px;
	height: 300px;
	display: flex;
}
.left {
	width: 500px;
	flex-shrink: 2;
  border:10px solid black;
  padding:60px;
	background: red;
}
.right {
	width: 400px;
  border:20px solid black;
  padding:40px;
	flex-shrink: 1;
	background: blue;
}

  </style>
  <body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
    </div>

  </body>
  <script src="" type="text/javascript" charset="utf-8"></script>
</html>
Copy the code
  • Excess part :640+520-600=560
  • Proportion: 5002:4001 = 5:2
  • Each block exceeds content: 5605/7 5602/7
  • .left Actual content: 640-560 *5/7 = 240
  • 520-560 *2/7 = 360

5.1.4 ensuring border width + padding + + margin

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="" />
  </head>
  <style type="text/css">
    * {
	padding: 0;
	margin: 0;
}
.container {
	width: 600px;
	height: 300px;
	display: flex;
}
.left {
	width: 500px;
	flex-shrink: 2;
  margin:0 10px;
  border:10px solid black;
  padding:60px;
	background: red;
}
.right {
	width: 400px;
  border:20px solid black;
  padding:40px;
  margin:0 20px;
	flex-shrink: 1;
	background: blue;
}

  </style>
  <body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
    </div>

  </body>
  <script src="" type="text/javascript" charset="utf-8"></script>
</html>
Copy the code
  • Excess :660+560-600=620
  • Proportion: 5002:4001 = 5:2
  • Each block exceeds content: 6205/7 6202/7
  • . Left Actual content: 660-620 *5/7 = 217.142
  • Right Actual content: 560-620 *2/7 = 382.857

It can be concluded from the above four cases that the excess part must be calculated by the actual content (width+border+padding+margin) while the ratio column is calculated by width, so the value of the real content is compressed

5.2 the flex – turns up

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="" />
  </head>
  <style type="text/css">
    * {
	padding: 0;
	margin: 0;
}
.container {
	width: 600px;
	height: 300px;
	display: flex;
}
.left {
	width: 100px;
	flex-grow: 3;      
	background: red;
}
.right {
	width: 200px;
  flex-grow:2;
	background: blue;
}

  </style>
  <body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
    </div>
  </body>
  <script src="" type="text/javascript" charset="utf-8"></script>
</html>
Copy the code
  • Extra :600-100-200=300
  • Ratio: 3:2
  • Each block exceeds content: 3003/5 3002/5
  • .left Actual content: 100 + 300*3/5 = 280
  • 200 + 300*2/5 = 320
<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="" />
  </head>
  <style type="text/css">
  /* The actual space is equal to the actual content size +padding+border+margin */
  /* The remaining space is equal to the actual content size minus the capacity of the outermost box */
  /* The proportion of the actual allocation is just the proportion of the actual content size */
  /* The ratio of grow to shrink is divided into columns of content size and then allocated according to the remaining space */
  /* If the grow and shrink values are already less than 1, they are already proportional */
    * {
	padding: 0;
	margin: 0;
}
.container {
	width: 600px;
	height: 300px;
	display: flex;
}
.left {
	width: 100px;
	flex-grow: 0.3;      
	background: red;
}
.right {
	width: 200px;
  flex-grow:0.2;
	background: blue;
}

  </style>
  <body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
    </div>
  </body>
  <script src="" type="text/javascript" charset="utf-8"></script>
</html>
Copy the code
  • Left width 100+300*0.3 = 190
  • Righ width 200+300*0.2 = 260