Original: itsOli @ front-end 10,000 hours this article was first published in the public number "front-end 10,000 hours" this article belongs to the author, without authorization, please do not reprint! This article is adapted from "sparrow" private pay column "front end | ten thousand hours from zero basis to easily obtain employment"Copy the code


❗ ️ ❗ ️ ❗ ️

The following link is the latest erratum to this articleLet the Box Move: ② “Positioning” and BFC


1. How many positioning methods are there? How to achieve positioning respectively? What are the reference points? What are the usage scenarios? 2. What does z-index do? How to use it? 3. What is BFC? How do I generate a BFC? What does the BFC do? Give an example. 4. In what scenarios does margin merging occur? How to merge? How do I keep margins from merging adjacent elements? Give me an example of a parent-child margin merge?Copy the code

🙋 on the question “refer to the answer in detail”, please click here to view access!



Introduction: In this article we will focus on positioning and how BFC makes the box move.

The learning method is still: open JS Bin, copy the code and run it to see the effect, and then fix each line of code.


1 What is “Positioning”

To “position” is to leave the normal document flow by setting the value of the Position property.


2. What are the categories of positioning

2.1 Relative Positioning

🔗 source code and effect display HTML

<div class="box1">1</div>
<div class="box2">2</div>
<div class="box1">3</div>
Copy the code

CSS

.box1..box2 {
  width: 50px;
  height: 50px;
  border: 2px solid;
}
.box2 {
  position: relative;
  /* 🚀relative is offset relative to its normal flow position. Visually, it has moved, but the amount of space it used to occupy in the document flow has not changed. For other elements, it is still there, so the position of other elements does not change. * /

  top: 10px;
  left: 10px;
}
Copy the code

2.2 Absolute Positioning

When you set it to absolute location, you are invisible to other elements on the document stream. I don’t think you exist! If there are more than one absolute location element, these absolute location elements are also invisible to each other.

🔗 source code and effect display HTML

<div class="box1">1</div>
<div class="box2">2</div>
<div class="box1">3</div>
Copy the code

CSS

.box1..box2 {
  width: 50px;
  height: 50px;
  border: 2px solid;
}
.box2 {
  color: red;
  position: absolute;
 
  top: 10px;
  left: 10px;

  /* ❓ offset with respect to whom? A: First of all, it looks for its parent element to see if it has a position in the parent element. This position includes relative, absolute, fix, and if so, relative to it. If not, look for the parent element from the parent element, if there is relative to it; If not, keep finding our body. * /
}
Copy the code

2.2.1 ❓ The absolute value is offset relative to the value

🔗 source code and effect display HTML

<div class="container">
  <div class="box1">1</div>
  <div class="box2">2</div>
  <div class="box1">3</div>
</div>
Copy the code

CSS

html {
  border: 3px solid blue;
  /* 3️ finally, if none, then box2's absolute positioning value relative to here is at an end. * /

}
body {
  margin: 40px;
  border: 1px solid red;
  /* 2️ secondly, if there is no position on the lower container and there is relative (position, absolute, fixed), the absolute positioning value of Box2 is relative to: position: relative; * /
}

container {
  margin-top: 40px;
  padding: 40px;
  background: yellow;
  /* 1️ first, if the parent element of Box2 has localization (relative, absolute, fixed), then the absolute localization value of Box2 is relative to: position: relative; ❗️ and relative is the best, because an element that sets relative but does not set its value is equivalent to not setting it. It's still in the normal flow, it's still a normal element, it's still in the same position, but it can be used as a relative anchor for its children. * /
}

.box1..box2 {
  width: 50px;
  height: 50px;
  border: 2px solid;
}
.box2 {
  position: absolute;
  top: 0px;
  left: 10px;
}

/* ❗️ Therefore, when we use absolute positioning, we must set up a reference point (anchor point) for positioning. In general, our absolute reference point is relative to its parent container. So the principle is: if an element is set to absolute, its parent container is set to relative. * /
Copy the code

2.2.2 z – index

Elements that use absolute positioning, like floating, have the “block box” properties.

Since the use of absolute positioning causes element overlays, z-index can solve the problem of overlays between elements by setting its cascading order. The larger the value of the same element, the closer it is to the visual point; Different parent elements, as long as the parent element is larger, then the whole is closer to the visual point, regardless of the size of the child elements.

  • Z-index: The pattern displayed on the display is a two-dimensional plane with x and y axes representing position attributes. In order to express the concept of three dimensions, such as displaying the superposition order of upper and lower elements, z-index attribute is introduced to represent the superposition order of an element on the Z axis. The element with a larger z-index value is superimposed on the element with a smaller z-index value. For positioned objects that do not specify this attribute, an object with a positive Z-index will be above it and an object with a negative z-index will be below it. The Z-index attribute applies to positioning elements (objects whose position attribute values are relative, Absolute or fixed). It is used to determine the stacking order of positioning elements in the direction perpendicular to the display screen (called the Z-axis). That is, if the elements are not positioned, The Z-index set to it will be invalid.

  • Same z-index who is up and who is down?

    • If neither element is positioned or if both elements are positioned and the z-index is the same, then the latter overwrites the former in document flow order.
    • If neither element is set to z-index, use the default, one positioned and one unpositioned, then the positioned element overrides the unpositioned element.
  • Father-son relationship handling:

    • If the z-index of the parent element is valid, the child element will be above the parent element regardless of whether the z-index is set.
    • If the z-index of the parent element is invalid (unpositioned or the default value is used), the z-index setting of the positioned child element takes effect.

2.3 Positioning

position: fixed;
Copy the code

Position relative to the browser window. So when scrolling occurs, the fixed positioning element remains in a certain position in the window.


3 use “Position” or “float”

  • Large layout, adaptive, with “floating” ———— floating general and responsive combination of more;

  • Small elements, fixed width and height, using “positioning” ———— is generally only applicable to some small ICONS;

🏆 combining the actual situation is the key. For example, unread messages on the profile picture of a web page, we usually choose to use “location” to achieve a good. Anything that covers anything else is “absolute positioning”.


4 small combat: implement navbar

🔗 source code and effect display HTML

<nav>
  <ul>
    <li><a href="#">Home page</a></li>
    <li><a href="#">works</a></li>
    <li><a href="#">More and more</a>
      <ul class="child">
        <li><a href="#">GitHub</a></li>
        <li><a href="#">blog</a></li> 
        <li><a href="#">zhihu</a></li>
      </ul>     
    </li>
  </ul>
</nav>
Copy the code

CSS

* {
  margin: 0;
  padding: 0;
}
ul {
  list-style: none;
}
a {
  color: # 333;
  text-decoration: none;
}
nav {
  width: 500px;
  margin: 10px auto 0;
  box-shadow: 0px 2px 4px 1px rgba(0.0.0.0.3);
  /* 🚀 the first and second values indicate the horizontal and vertical offsets of the shadow; 4px represents ambiguity; 1px is an extension of this blur; Rgba is this fuzzy color. * /
}
nav::after {
  content: ' ';
  display: block;
  clear: both;
}
/* 🚀 Since we are using floats, we need to clear floats to prop up the parent container. * /

nav>ul>li {
  position: relative;
  /* 🚀🚀🚀 add an anchor point to the absolute location offset of.child. * /

  float: left;
  /* 🚀 arranges the li's in the selector hierarchy horizontally. * /

}
nav>ul>li:hover .child {
  display: block;
}
/* 🚀🚀. Child is hidden by default and only displayed as block when I mouse over "more" li. * /


nav a {
  display: block;
  padding: 10px 10px;
  /* Remember, we need the padding on the A link if we want to click on a large range. If you add padding on li, the range is still on the word. Note, however, that since the a link is an inline element, if you add only the padding, the width and height of the link will not change, but the background color will become larger, which will cause many consequences such as "occlusion". So we need to make it appear as a block. We didn't use inline-block because using inline-block, meaning it also has inline properties, causes "shrinkage" -- meaning the width is determined by the width of the text content. To spread it out, regardless of the width of the content, you need to use blocks. * /

  min-width: 50px;
  /* The "minimum width" is used to spread the text inside the a link so that any clickable text does not wrap. * /
}
nav a:hover {
  color: #fff;
  background: rgba(0.0.0.0.4);
}
nav .child {
  position: absolute;
  /* 🚀🚀🚀 sets the absolute location so that we can place the.child wherever we want, because the parent container cannot find it. Other methods (such as floating, or no use) will not achieve the desired effect. * /

  top: 100%;
  /* 100% 就表示按照 li 的高度。 */

  box-shadow: 0px 2px 4px 1px rgba(0.0.0.0.3);
  display: none;
  /* 🚀🚀. Child is "hidden" by default -- display: none; When I mouse over "more" Li. * /
}
Copy the code


5 BFC

❗ ️ front knowledge, please read the article: “the basic visual formatting (07) CSS: (1)” block box “formatting | CSS” the basic visual formatting (08) CSS: (2) “inline box” formatting | CSS”

  • In normal flow, boxes belong to either a block-level formatting context or an inline formatting context. Each render area is represented by a fomating context, which determines how its children are positioned and how they interact with other elements. BFC Block Formating Context.

  • BFC is a separate render area with only block-level box participation. It dictates how the internal block-level box is laid out and has nothing to do with the outside of the area.

5.1 Which elements will have BFC conditions

If the display attribute is block, list-item, or table, BFC is generated. That is, block elements.

5.2 When can elements generate BFC

  • The float property is not None:

If an element adds an attribute called float, the element itself generates a block-level formatting context.

  • Position is absolute or fixed.
  • Display inline-block, table-cells, flex, or inline-flex;
  • Overflow is not visible (hidden, auto, scroll).

We want to understand this BFC because we want to understand its characteristics to achieve some of the effects we need. Or when a problem arises, we can explain the problem, understand why, and then solve it or find an alternative.

5.3 BFC Layout Rule features

  • ① in BFC, boxes are arranged vertically one after the other from the top;

  • (2) The vertical distance of the box is determined by the margin. The margins of two adjacent boxes belonging to the same BFC will overlap.

  • ③ in the BFC, the left margin of each box should touch the left side of the containing block (for left-to-right formatting, otherwise the opposite). Even if there is a float!

  • (4) the area of BFC will not intersect with the floating box, and is close to the floating edge;

  • ⑤ : When calculating the height of BFC, the height of the floating box is also involved in the calculation;

  • ⑥ : A BFC is a separate container on the page. The child elements in the container do not affect the outside elements. And vice versa!

5.4 Common BFC Functions

  • Clears internal float of elements

Corresponding rules: ⑤ When calculating the height of BFC, the height of the floating box is also involved in the calculation.

  • Solve the margin merge problem

Corresponding rules: (2) The vertical distance of boxes is determined by margin, and the margins of two adjacent boxes belonging to the same BFC will overlap.

  • Make an adaptive two-column layout

3. In the BFC, the left margin of each box should touch the left of the containing block (for left-to-right formatting, otherwise the opposite). Even if there is a float!

(4) The area of BFC does not intersect with the floating box and is close to the floating edge.

5.4.1 Clear internal float of elements

❌ question: 🔗 source code and effect display

<ul class="navbar">
  <li><a href="#">1 page</a></li>
  <li><a href="#">2 products</a></li>
  <li><a href="#">3 service</a></li>
  <li><a href="#">4 about</a></li>
</ul>
Copy the code
.navbar {
  list-style: none;
  border: 1px solid #ccc;
  /* Add a background color and no effect: background: pink; * /

}
.navbar>li {
  float: left;
  margin-left: 15px;
}

/* 🚀 The floating element is invisible to its parent element because it is separated from the document stream. Here for Navbar, he thinks there's nothing in there to prop it up, because li has already floated, so there's nothing to prop it up, so it thinks the height is zero. * /
Copy the code

✔️ Solution:

  • Removed by “float” to solve, in the article “(10) for” box “to move: (1) floating | CSS” has answer;

  • By creating a BFC for the parent element, addoverflow: hidden;Style:

Corresponding rules: ⑤ When calculating the height of BFC, the height of the floating box is also involved in the calculation.

🔗 source code and effect display

<ul class="navbar">
  <li><a href="#">1 page</a></li>
  <li><a href="#">2 products</a></li>
  <li><a href="#">3 service</a></li>
  <li><a href="#">4 about</a></li>
</ul>
Copy the code
.navbar {
  list-style: none;
  border: 1px solid #ccc;
  overflow: hidden;
}
.navbar>li {
  float: left;
  margin-left: 15px;
}
Copy the code

5.4.2 Solve the problem of margin merging

❌ problem: in the article the basic visual formatting (07) CSS: (1) “block box” formatting | CSS “, we know that:

Another important aspect of vertical formatting is the merging of vertical adjacent margins. This merging behavior only applies to margin. If an element has a padding and border, the padding and border are not merged. When two or more vertical margins meet, they will form a single margin whose height is equal to the greater of the heights of the two overlapping margins. ❗️ Note: when an element is contained within another element, margin-bottom and magin-top adjacent to each other will also be superimposed, whichever is larger.

🔗 source code and effect display

<div class="box1">1</div>
<div class="box2">2</div>
Copy the code
.box1 {
  color: #fff;
  width: 100px;
  height: 100px;
  margin-bottom: 50px;
  background: blue;
}

.box2 {
  color: #fff;
  width: 100px;
  height: 100px;
  margin-top: 100px;
  background: pink;
}
Copy the code

✔️ workaround: Place vertical boxes in different BFC so margins don’t overlap.

Corresponding rules: (2) The vertical distance of boxes is determined by margin, and the margins of two adjacent boxes belonging to the same BFC will overlap.

🔗 source code and effect display

<div class="box1">1</div>

<div class="ct">
  <div class="box2">2</div>
</div>
<! 🚀 We wrap a container around box2 and trigger it to generate a BFC. Then the two boxes do not belong to the same BFC, so there will be no margin overlap! -->
Copy the code
.ct {
  overflow: hidden; /* 🚀 triggers the container to generate a BFC */
}

.box1 {
  color: #fff;
  width: 100px;
  height: 100px;
  margin-bottom: 50px;
  background: blue;
}

.box2 {
  color: #fff;
  width: 100px;
  height: 100px;
  margin-top: 100px;
  background: pink;
}
Copy the code

5.4.3 Make an adaptive two-column layout

❓ problem: in the article (10) for “box” to move: (1) floating | CSS “, by adding our margin – left or margin – the right way to make “gap” of the effect of the two-column layout.

❗️ But what if you want a two-column layout with no gaps in the middle?

❌ due to:

③ In the BFC, the left margin of each box should touch the left side of the containing block (for left-to-right formatting, otherwise the opposite). Even if there is a float!

🔗 source code and effect display

<div class="aside">The sidebar is fixed in width</div>
<div class="main">Hey guys, I'm distributing a series of articles from the "Front 10,000 Hours" column on this platform.<br>For this column I have written about "From zero to Employment".<br>"From zero to Employment" includes 150+ essays and 300+ classic written and interview questions.<br>If you are interested in this series of articles, please follow our official account: Front 10,000 hours, and click on the menu bar "Easy to join" to join our 10,000 hours project! Zhu shunli ^ ^...</div>
Copy the code
.aside {
  color: #fff;
  width: 150px;
  height: 100px;
  background: red;
  float: left;
}
.main {
  color: #fff;
  background: blue;
  height: 200px;
}
Copy the code

✔️ Solution:

(4) The area of BFC does not intersect with the floating box and is close to the floating edge.

By triggering Main to generate BFC, the adaptive seamless two-column layout is realized:

🔗 source code and effect display

.main {
  overflow: hidden; /* 🚀 triggers the BFC */
}

.aside {
  color: #fff;
  width: 150px;
  height: 100px;
  background: red;
  float: left;
}
.main {
  color: #fff;
  background: blue;
  height: 200px;
}
Copy the code



Postscript: Through two brother articles, we kind of made the “box” move. In the next three articles, we will make “the moving box” more elegant.

I wish you good, QdyWXS ♥ you!


🏆 answers readers’ questions: