Problem description

Let’s start with a requirements scenario:

In the figure above, you need to achieve equal horizontal spacing between child elements and between child elements and parent container borders.

There are many ways to do this, but what we’re going to discuss here is: How do you do it succinctly using Flex layout? The approach I’m using here is to use automatic margins to align on the main axis.

This article will focus on the application of margin, not justice-content: space-instituted; To implement.

Automatic margins are aligned on the main axis

Let’s take a look at MDN’s explanation of this:

. Automatic margins take up all the extra space – setting automatic left and right margins on a block can center it. Taking up as much space as possible on both sides, the block is placed in the middle.

This makes sense: automatic margins will bistil all the remaining space. Let’s try this out, with the following code:

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
Copy the code
.container {
  display: flex;
  align-items: center;
  box-sizing: border-box;
  border: 2px dashed #7cb305;
  width: 600px;
  height: 200px;
  margin: auto;
}


.item {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
  width: 100px;
  height: 100px;
  background: #722ed1;
  border-radius: 50%;
  color: #fff;
  font-size: 22pt;
}
Copy the code

Then look at the results:

That doesn’t seem right. If you look at the spacing between the children, it’s about twice as big as the spacing between the children and the border, which is not what you’d expect. According to MDN, automatic margins divide the remaining space equally, but why does this happen? Now let’s talk about my understanding.

The relationship between the “allocation weight” of spindle remaining space and the automatic margins of child elements

This allocation weight relation has not been explained in MDN. It is purely a personal opinion. We can understand it as follows:

  • If a child element is declared on a region (or direction) of the main axismargin-*: autoSo the weight of this space is plus 1
  • If another child element has an automatic margin declaration on the same region (or direction), then the weight is assigned plus 1
  • On these regions where automatic margins are declared, the remaining space is divided according to allocation weights

First, this understanding clearly satisfies the MDN interpretation. Then let’s take a look at the picture above:

  • We put theChild element 1The region to the left of theSpacing area 1.Child element 1The region to the right of theSpacing area 2
  • Child element 1There are automatic margins to the left and right of, soThe weight of spacing region 1 = 1.The weight of spacing region 2 = 1
  • Child elements 2There are automatic margins to the left and right of, soThe weight of spacing region 2 = 1 + 1 = 2
  • The lastWeight of spacing region 1Weight of spacing region 1It’s a 1:2 relationship
  • The other areas are followed by analogy, and finally the spacing area is divided according to the weight

We can then adjust the code based on this understanding by declaring automatic margins once on each separated region:

  • First of all, let’s take.itemOn this patternmarginTo get rid of
  • Then only in HTMLChild element 1Child elements 3Set onstyle="margin: 0 auto"

The adjustment is as follows:

<div class="container">
  <div class="item" style="margin: 0 auto">1</div>
  <div class="item">2</div>
  <div class="item" style="margin: 0 auto">3</div>
</div>
Copy the code
.container {
  display: flex;
  align-items: center;
  box-sizing: border-box;
  border: 2px dashed #7cb305;
  width: 600px;
  height: 200px;
  margin: auto;
}


.item {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100px;
  height: 100px;
  background: #722ed1;
  border-radius: 50%;
  color: #fff;
  font-size: 22pt;
}
Copy the code

OK, problem solved. Based on this understanding, there is another setting that can achieve the same effect:

<div class="container">
  <div class="item" style="margin-left: auto">1</div>
  <div class="item" style="margin: 0 auto">2</div>
  <div class="item" style="margin-right: auto">3</div>
</div>
Copy the code

Codepen. IO/deepFunc/PE…