This is the sixth day of my participation in the August More Text Challenge.

The principle of Flex

Let’s take a look at how to implement a Flex layout.

First of all, Flex layout supports landscape and portrait, so we need to make an abstraction. We call the direction in which Flex extends “main axis” and the direction perpendicular to it “cross axis”. Thus, the Width and height in the Flex entry are referred to as cross axis dimensions or spindle dimensions.

Flex supports reverse layout, so we need to abstract the cross axis start, cross axis end, spindle start, and spindle end, which could be top, left, bottom, or right.

There is a special case in Flex layout where the Flex container is not specified with the spindle size. In this case, the Flex property is actually useless at all. All Flex dimensions can be treated as 0, and the spindle size of the Flex container is equal to the sum of all other Flex items’ spindle sizes.

Next, let’s do Flex layout.

The first step is to split the Flex item. A Flex item with a Flex attribute can be assumed to have a spindle size of 0, so it must be placed in the current line.

Next we put the Flex items on the row one by one, and without allowing line breaks, we “mindlessly” put the Flex items on the same row. To allow line breaks, we set the remaining spindle space to the Flex container spindle size, subtract the remaining spindle space from the Flex container spindle size each time a Flex item doesn’t fit, change to the next line and repeat.

As we branch, we incidentally calculate two properties for each row: the cross axis size, which is the maximum of all cross axis sizes in the row, and the remaining spindle space, which was mentioned earlier.

The second step is to calculate the spindle size and position of each Flex item.

If the Flex container does not allow line breaks and the spindle size ends up outside the Flex container, scale equally.

If the Flex container has more than one row, then according to our previous branch algorithm, there must be free space in the main axis. In this case, we need to find all Flex items in the row with Flex attributes, and divide the free space between them in Flex proportion.

Once done, we can determine the spindle position coordinates of each Flex item based on the spindle layout direction.

If there is no Flex item with flex attributes on the line at all, the precision-content mechanism is in effect, and several different values affect how the remaining white space is allocated. As implementers, we simply add a value when calculating the flex item coordinates.

For example, if flex-start is applied to the first Flex item, if center is applied to half the size of the first flex item, and if space-between is applied to every flex item except the first flex item, the number of Flex items minus one is applied.

The third step is to calculate the cross axis size and position of the Flex entry.

The intersecting axis is computed first by calculating the position of each line according to align-content, which is very similar to justify-content.

Locate each element in the line according to alignItems and the Flex item’s alignSelf.

Once the axes and cross axes are computed, the coordinates and dimensions of each Flex entry are determined, and the flex layout is complete.

The Flex application

Let’s try using Flex typography to solve three of the classic CSS problems of the year (a piece of cake).

Vertically centered:

<div id="parent">
  <div id="child">
  </div>
</div>
Copy the code
#parent {
  display:flex;
  width:300px;
  height:300px;
  outline:solid 1px;
  justify-content:center;
  align-content:center;
  align-items:center;
}
#child {
  width:100px;
  height:100px;
  outline:solid 1px;
}
Copy the code

The idea is to create a flexbox with only one line, and then use align-items: Center; And align the content: center; To make sure that the row is in the container and the element is in the row.

Two rows of equal height:

<div class="parent"> <div class="child" style="height:300px;" > </div> <div class="child"> </div> </div> <br/> <div class="parent"> <div class="child" > </div> <div class="child" style="height:300px;" > </div> </div>Copy the code
.parent {
  display:flex;
  width:300px;
  justify-content:center;
  align-content:center;
  align-items:stretch;
}
.child {
  width:100px;
  outline:solid 1px;
}
Copy the code

The idea is to create a flexbox with just one row, and then use the Stretch property to make each element equal to the row height.

Adaptive width:

<div class="parent">
  <div class="child1">
  </div>
  <div class="child2">
  </div>
</div>
Copy the code
.parent {
  display:flex;
  width:300px;
  height:200px;
  background-color:pink;
}
.child1 {
  width:100px;
  background-color:lightblue;
}
.child2 {
  width:100px;
  flex:1;
  outline:solid 1px;
}
Copy the code

This is the basic capability of Flex design, simply by adding Flex attributes to the elements that you want to adapt.