The correct use of the FlexBox layout

In the project, we will also use a lot of the old and new properties of flexbox, but most people generally only write new properties. The old properties are handled by autoprefixer, but in fact, the new and old properties that complete the same function are expressed not exactly. Some people only use the “universal” flex:number property to allocate space for flexible items, but some special situations cannot be satisfied. This article sorts out the difference between the old and new properties of flexbox and the principle of space allocation, and uses flexbox layout for everyone. The project is open to all channels.

Flexbox compatibility

PC compatibility

Mobile compatibility

As shown above, in order to be compatible with IE10-11 and Android4.3-, UC, we still need to use the old properties of Flexbox.

Flexbox new and old attributes

Flexbox’s new attributes provide many functions that the old version did not have, but currently Android4.x and UC still have a certain market share and need to be compatible, so currently only use Functions that both new and old properties have.
The old and new attributes of Flexbox that can achieve the same function are as follows:

But the imagination is beautiful, the reality is cruel, there are a few stubbornness in the old and new attributes Molecules cannot behave the same obediently, there is always a little difference.
Let’s take a look at which of the new and old properties are different:

flex-direction:row-reverse vs box-orient:horizontal;box-direction: reverse

Same point: change the main axis direction and the order of the telescopic items; under ltr, the telescopic items are arranged from right to left.
Different points:

flex-direction:row-reverse: the first flexible item is aligned to the starting point of the main axis

box-orient:horizontal;box-direction:reverse: align the last telescopic item to the end of the main axis

flex-direction:column-reverse vs box-orient:vertical;box-direction:reverse

Same point: change the main axis direction and the order of flex items ; The telescopic items are arranged from bottom to top under ltr.
Different points:
flex-direction:column-reverse: The first flex item is aligned to the starting point of the main axis.

box-orient:vertical;box-direction:reverse: the last telescopic item is aligned to the end of the main axis.

oreder:integer vs box-ordinal-group:integer

Same Point: Define the display order of the telescopic items.
Different points:
oreder:integer: The default value is 0; it can be a negative value.
box-ordinal-group:integer: The default value is 1; the value is greater than 1.

flex-grow:number vs box-flex:number

Same point: define the expansion factor of the flex project.
Different points: box-flex:number also defines the shrinking factor of the flex item.

flex-shrink:number vs box-flex:number

Same point: Define the shrinking factor of the flex item.
Different points: box-flex:number also defines the expansion factor of the flex item.

How Flexbox allocates space

There are three properties that affect the allocation of space in Flexbox layout, namely flex-grow and flex-shrink And flex-basis.

  • flex-grow: When the total width of the flex-grow item in the main axis direction

  • flex-shrink: When the total width of the flex-shrink item in the main axis direction> the flex container, the flex item allocates the total width beyond the flex container according to the shrinking factor space.

  • flex-basis: Flex-basis. Before calculating the remaining space or exceeding the space, reset the width of the flex item and then calculate it.

Let’s first take a look at how to calculate the stretched item width after stretching, first give a simple and clear formula, and then verify it through chestnuts.

Stretch project expansion width = (project container width-project width or the sum of the project settings flex-basis) * corresponding flex-growProportion

The width of the stretched item after stretching = the original stretched item width + the expanded width

.flexbox-wrap{
width:550px;
display: flex;
}
.flexbox-item{
&:nth-child(1){
width:60px;
}
& :nth-child(2){
width:70px;
}
&:nth-child(3){
flex-basis:80px;
}< br /> &:nth-child(4){
flex-basis:90px;
}
&:nth-child(5){
flex-basis:100px;
}
}
@for $i from 1 through 5 {
.flexbox-item:nth-child(#{$i}){
flex-grow : $i;
background-color: rgba(35 * (6-$i), 20 * $i, 35 * $i,1);
}
}

Let’s calculate the stretched width of the first stretched item in the chestnut above.
Corresponding to the formula step by step calculation:

// Item container width
container = 550
// Item width or the flex-basis sum of item settings
itemSum = 60 + 70 + 80 + 90 + 100 = 400
// The flex-grow ratio corresponding to the first stretch item
flexRatio = 1 / (1 + 2 + 3 + 4 + 5) = 1 /15
// The expanded width of the first stretch item
extendWidth = (550-400) * 1/15 = 10
// The stretched width of the first stretch item
itemWidth = 60 + 10 = 70

After calculation, the stretched width of the first stretchable item is 70px. We use the box model on chrome to see if it is correct.

The result calculated by chrome is consistent with the result we calculated.

Is it easy to deduce the calculation formula of compression based on the calculation formula of stretching?

Expandable project shrinking width = (Project width or the sum of project settings flex-basis-project container width) * Corresponding flex -shrink ratio

The width of the project after compression = the original width of the project-reduced width

Continue to use a chestnut to verify that the formula is correct

 .flexbox-wrap{
width:250px;
display: flex;
}
.flexbox-item{
&:nth-child(1){
width:60px;
}
&:nth-child(2){
width:70px;
}
&:nth-child(3){
flex-basis:80px;
}
&:nth-child(4){
flex-basis:90px;
}
&:nth -child(5){
flex-basis:100px;
}
}
@for $i from 1 through 5 {
.flexbox-item:nth- child(#{$i}){
flex-shrink: $i;
background-color: rgba(35 * (6-$i), 20 * $i, 35 * $i,1 );
}
}

Let’s calculate the compressed width of the first stretchable item in the chestnut above.
Corresponding to the formula step by step calculation:

// Item container width
container = 250
// Item width or the flex-basis sum of item settings
itemSum = 60 + 70 + 80 + 90 + 100 = 400
// The flex-shrink ratio corresponding to the first stretch item
flexRatio = 1 / (1 + 2 + 3 + 4 + 5) = 1 /15
// The reduced width of the first stretch item
extendWidth = (400-250) * 1/15 = 10
// The compressed width of the first stretch item
itemWidth = 60-10 = 50

After calculation, the compressed width of the first telescopic item is 50px. We use the box model on chrome to see if it is correct.

The result calculated by chrome is not the same as the result we calculated.

The calculation method of the compression of the stretch project is different from that of the stretch. -shrink is modified to 10, the reduced width is now ( 400-250) * (10 / 24) = 62.5, the reduced width is larger than the original width, the calculated compressed The width becomes a negative number.

In order to avoid this extreme situation, calculating the reduction ratio is to consider the original width of the stretched item.

The correct formula is like this

The shrinking project width = (the project width or the sum of the flex-basis settings of the project-the project container width) (corresponding flex-shrink the project width or the flex-basis ratio set by the project)

The width of the project after compression = the width of the original project-reduced width

Corresponding Calculate step by step with the formula:

// Item container width
container = 250
// Item width or flex-basis sum of item settings
itemSum = 60 + 70 + 80 + 90 + 100 = 400
// The flex-shrink ratio corresponding to the first stretch item
flexRatio = (1*60) / (1*60+2*70+3*80+ 4*90+5*100) = 6/130
// The first stretch item to shrink the width
extendWidth = (400-250) * 6/130 ≈ 6.922
// First The compressed width of a stretchable item
itemWidth = 60-6.922 = 53.078

After calculation, the compressed width of the first stretchable item is 53.078px, which is the same as the box model on chrome .

Flexbox property abbreviation trap

The above-mentioned flex-grow, flex-shrink and flex-basis< /code>There is an abbreviation of flex.

flex: flex-grow [flex-shrink] [flex-basis]

flex Values ​​of various abbreviations

  • flex: initial == flex: 0 1 auto

  • flex: none == flex: 0 0 auto

  • flex: auto == flex: 1 1 auto

  • flex: number == flex: number 1 0%

In actual projects, Directly write the abbreviated flex to allocate space for the flexible project, but using the abbreviated attribute will leave some traps, leading to unsatisfactory performance results.

Use flex and flex-grow to stretch the flex items to fill the container and see the difference in performance.

First look at the effect of using flex-grow to stretch and stretch the project

.flexbox-wrap{
width:550px;
display: flex;
}
.flexbox-item{
flex-grow:1;
&:nth-child(1){
width:60px;
}
&:nth-child(2){
width:70px;
}
&:nth-child(3){
width: 80px;
}
&:nth-child(4){
width:90px;
}
&:nth-child(5){
width:100px;
}
}
@for $i from 1 through 5 {
.flexbox-item:nth-child(#{$i}){
background-color: rgba(35 * (6-$i), 20 * $i, 35 * $i,1);
}
}

Each telescopic item Stretch the same width over the original width

Through the above calculation of the stretched stretched item width, the stretched width of the first stretched item can be calculated< /p>

// Item container width
container = 550
// Item width or flex-basis sum of item settings
itemSum = 60 + 70 + 80 + 90 + 100 = 400
// The flex-grow ratio corresponding to the first flex itemflexRatio = 1 / (1 + 1 + 1 + 1 + 1) = 1/5
// The first stretch item extended width
extendWidth = (550-400) * 1/5 = 30
// The stretched width of the first stretch item
itemWidth = 60 + 30 = 90

Then we replace flex-grow:1 with flex:1, the following is the performance effect, the stretched width of the stretched item becomes the same.

From the chrome box model, you can see that the width of the stretched item becomes 110px, and the stretchable container divides the container equally width.

flex:1 after expansion is flex:1 1 0%, flex-grow :1 is equivalent to flex:1 1 auto. The difference between the two lies in the value of flex-basis. flex:1 resets the width of the item to 0, so the allocable space is the entire container, which can be more intuitively understood from the formula calculation:

// Item container width
container = 550
// Item width or flex-basis sum of item settings
itemSum = 0 + 0 + 0 + 0 + 0 = 0
// The flex-grow ratio corresponding to the first flex item
flexRatio = 1 / (1 + 1 + 1 + 1 + 1) = 1/5
// The expansion width of the first flex item
br />extendWidth = (550-0) * 1/5 = 110
// The stretched width of the first stretch item
itemWidth = 0 + 110 = 110

Flexbox features that need attention

Invalid attributes

  • column-*invalid in the flex container

  • float and clear is invalid in the scaling project

  • vertical-align is invalid in the scaling project

  • ::first-line and ::first- Letter is invalid in the flexible container

The non-empty character text node in the flexible container is also a flexible item

< br /> 1
2
I am a fake text
< span class="flexbox-item">3
4
5

margin folding

  • Retractable container and retractable project Margin will not collapse

  • The margin between stretchable items will not collapse

BUG of the old version of Flexbox

< p>If you want to add display:block; or display:flex for in-line elements for flexible items End, questions and corrections are welcome. It is not easy to write an original article. If this article is helpful to you, please like, recommend and follow the author for support.

Leave a Comment

Your email address will not be published.