Flex layout and scaling calculation

Posted May 28, 20209 min read

1. Introduction to Flex Layout

Flex is the abbreviation of Flexible Box, which means "flexible layout", and is used to provide maximum flexibility for the box model.

Any container can be specified as a Flex layout, that is, inline elements can also be set as a Flex layout.

//Set the block-level element div to flex layout
div {
display:flex;
}

//Set the span of inline elements to flex layout
span {
display:flex;
}

Elements that use the Flex layout are called Flex container(flex container), or "container" for short. Its all child elements automatically become container members, called Flex item(flex item), referred to as "item".

Second, the default features of Flex layout

By default, all child elements in the container will be arranged horizontally, similar to forcing a left float, so the float and clear attributes of the child elements of the container will become invalid. At the same time, the alignment of the child elements in the container will not be controlled by vertical-align , which means that vertical-align will also be invalid.

<style>
#main {
width:800px;
height:300px;
display:flex;
font-size:20px;
background:red;
}
</style>

<div id = "main">
<div style = "background-color:coral;" class = "item-1"> Red </div>
<div style = "background-color:lightblue;" class = "item-2"> Blue </div>
<div style = "background-color:lightgreen;" class = "item-3"> Green with more content </div>
</div>

** ** In no vertical alignment is set for the container At the same time the child element of the container is not set the height, then the height of the child element of the container is the same as the height of the container **, As above, the height of all child elements in the container will become 300px.

** ** By default, the width of the child elements under the container will not be automatically enlarged, that is, the default is to display the actual width of the element itself **. as the picture shows:

** ** By default, the width of the child elements under the container can be reduced , when the sum of the width of all the child elements in the container exceeds the width of the container, By default, no line break display , Then you need to reduce the width of the child elements of the container to ensure that the container can accommodate all the child elements . However, the width of the child elements of the container is not infinitely reduced, that is, shrink until it cannot be shrunk **.

.item-1 {
width:200px;
}
.item-2 {
width:8800px;
}
.item-3 {
width:8800px;
}

For example, above, the width of item2 and item3 is set to 8800px, and the width of all child elements in the container is 17800px, which is far beyond the width of the container 800px, so all child elements in the container must be compressed proportionally, item1 element The width of the strain should be 200-191.01 = 8.99px, and the minimum item1 is compressed to the width required to store a word **, which is exactly equal to the size of the font, which is 20px, so the width of item1 will become 20px.

** ** By default, the child elements in the container can be compressed to the minimum, but When compressed to the minimum, still can not put all the child elements, then the child elements will be placed in the container Outside .

** ** If you add a vertical alignment to the container, the height of all child elements in the container will become the actual height, **will not be the same height as the container
.

#main {
width:800px;
height:300px;
display:flex;
font-size:20px;
background:red;
align-items:flex-start;/* Add vertical alignment * /
}

Three, container property settings

The container has two axes by default:horizontal main axis and vertical cross axis. The main thing is to set the main axis direction of the container, whether to exceed the container to display the line break, horizontal alignment mode, vertical alignment mode
** flex-direction:Used to **set the direction of the main axis, the default value is row, which means all child elements in the container are arranged horizontally.

column:indicates that all child elements in the container are arranged vertically row-reverse :means reverse the order of all child elements in the container , and the starting point is to the right, that is aligned to the right .

**column-reverse
:means reverse the order of all child elements in the container, and the starting point is lower, that is aligned by the bottom of the container.

** flex-wrap:Used to **set whether to wrap when the child element in the container cannot be placed. The default value is nowrap, which means do not wrap, even if it cannot be put down.

wrap:indicates that can be wrapped, when set to wrap can wrap, the elements in the container will not be compressed, but will be displayed by wrapping.

#main {
width:800px;
height:300px;
display:flex;
background:red;
flex-wrap:wrap;/* Wrap when you can't put it down * /
font-size:20px;
}
.item-1 {
width:300px;
}
.item-2 {
width:300px;
}
.item-3 {
width:300px;
}

wrap-reverse:It means reverse the line arrangement order after line break display.

wrap:

wrap-reverse:

** ** flex-flow:It is the short form of flex-direction attribute and flex-wrap attribute. The default value is row nowrap, that is, the main axis is horizontal, and there is no line break.

** ** justify-content:Used to set the alignment mode of spindle direction.

** ** align-items:Used to set the alignment of items on cross axis(non-spindle).

Fourth, the element(project) property settings in the container

** order:Used to **set the order of container elements, the default value is 0 , the smaller the value, the higher the arrangement.

.item-2 {
order:-1;/* Set the order of item-2 to -1, you can make item-2 in front * /
}

** flex-grow:Used to **set the magnification ratio of the container element, the default value is 0 , that is, if there is remaining space, it will not be enlarged **.

** flex-shrink:Used to **set the reduction ratio of container elements, the default value is 1 , that is, if there is not enough space, the project will shrink.

** flex-basis:Used to **set the size of the container element, the default value is auto , that is, same as the actual size of the container element . When zooming, it will be calculated based on this value whether there is extra zoom space **.

** flex:short for flex-grow, flex-shrink, flex-basis, the default value is **0 1 auto, which means not zoomable, zoomable, The size is the same as the size of the container element, the latter two attributes are optional.

.item-2 {
flex:0 1 auto;/* Note that there is a space between the three values   and not a comma * /
}

** align-self:Used to **set the alignment of a container element separately, the default value is auto , which means inherit the alignment of the parent element **.

.item-2 {
align-self:center;/* Set item-2 center alignment separately * /
}

Five, the difference between felx:1 and flex:auto

From the above, the default value of flex is 0 1 auto. The value of flex is more flexible, and you can set a variety of values, such as:
** ** none:This is equal to 0 0 auto.

.item {
flex:none; //value is none
}
//Equivalent to
.item {
flex-grow:0;
flex-shrink:0;
flex-basis:auto;
}

** auto:Now equal to **1 1 auto.

.item {
flex:auto; //value is auto
}
//Equivalent to
.item {
flex-grow:1;
flex-shrink:1;
flex-basis:auto;
}

A non-negative number:At this time, this non-negative number refers to the value of flex-grow, flex-shrink uses the default value of 1, but flex-basis value is 0%, Such as:

.item {
flex:1; //value is a non-negative number
}
//Equivalent to
.item {
flex-grow:1;
flex-shrink:1;
flex-basis:0%;/* Here is a special 0%* /
}

The values are two non-negative numbers:At this time, they represent the values of flex-grow and flex-shrink, respectively, flex-basis value is 0%.

.item {
flex:6 8; //value is two non-negative numbers
}
//Equivalent to
.item {
flex-grow:6;
flex-shrink:8;
flex-basis:0%;/* Here is a special 0%* /
}

A length or percentage:At this time this value is the value of flex-basis, flex-grow takes the value 1, flex-shrink takes the value 1

.item {
flex:200px; //value is a pixel value
}
//Equivalent to
.item {
flex-grow:1;
flex-shrink:1;
flex-basis:200px;
}

.item {
flex:100%; //value is a percentage
}
//Equivalent to
.item {
flex-grow:1;
flex-shrink:1;
flex-basis:100%;
}

It should be noted that if flex-basis is set as a percentage, then the relative is the percentage of the size of the container, not the percentage of its own size.

As can be seen from the above, when the value of flex is none or auto or not set, the value of flex-basis is auto ; other cases such as When the value of flex is the number , the value of flex-basis is 0%.

So the difference between flex:1 and flex:auto is that the value of flex-basis is different, when flex:1 is 0%flex-basis ; when flex:auto, flex- The value of basis is auto.

Sixth, container element enlargement or reduction value calculation

** Zoom in situation**
It is mainly based on the value of flex-basis to calculate whether there is remaining space in the container. If there is free space, and a child element in the container can be enlarged, then use this child element The flex-grow value is the sum of the flex-grow values of all the child elements in the container to calculate the magnification factor of the child elements of the container, and then multiplied by the size of the remaining space is The pixel value of the child element of the container to be enlarged.

#main {
width:800px;
height:300px;
display:flex;
background:red;
font-size:20px;
}
.item-1 {
width:200px;
flex:2 1 auto;
}
.item-2 {
width:200px;
flex:3 1 10%;/* The flex-basis value is equivalent to 80px * /
}
.item-3 {
width:100px;
flex:0 1 220px;
}

Itme-1's flex-basis is auto, so the value is the same size as the element itself, ie 200px;
The flex-basis of item-2 is 10%, and its relative size is the size of the container itself, that is 800px \ * 10%= 80px;
Item-3's flex-basis is 220px set by. It should be noted here that although width is set to 100px, width will not have any effect. will still be based on flex-basis
First calculate the remaining space according to flex-basis = 800px-(200px + 80px + 220px) = 300px;
Since the remaining space is 300px> 0, the child elements in the container can be enlarged, because the flex-grow value of item-3 is 0, so item-3 will not be enlarged, still displayed at 220px.
item-1 magnification = 2/(2 + 3) \ * 300px = 120px;
item-2 magnification = 3/(2 + 3) \ * 300px = 180px;
So, the final size of item-1 = 200px + 120px = 320px;
item-2 size = 80px + 180px = 260px;
item-3 size = 220px;

** Shrinking situation**
The reduction is also based on the value of flex-basis to calculate how much space the container exceeds the container, but it is not simply based on the value of flex-shrink to calculate the zoom ratio, but based on an element in the container The flex-basis value multiplied by the flex-shrink value accounts for the sum of the flex-basis multiplied by the flex-shrink value of all child elements in the container to calculate the scaling ratio.

#main {
width:800px;
height:300px;
display:flex;
background:red;
font-size:20px;
}
.item-1 {
width:200px;
flex:0 2 auto;
}
.item-2 {
width:200px;
flex:0 3 100%;/* The flex-basis value is equivalent to 800px * /
}
.item-3 {
width:100px;
flex:0 0 200px;
}

Itme-1's flex-basis is auto, so the value is the same size as the element itself, ie 200px;
The flex-basis of item-2 is 100%, and its relative size is the size of the container itself, that is 800px \ * 100%= 800px;
Item-3's flex-basis is set to 200px . It should be noted here that although width is set to 100px, width will not have any effect. will still be based on flex-basis .
First calculate the excess space according to flex-basis =(200px + 800px + 200px)-800px = **400px
;
Since the excess space is 400px> 0, the child elements in the container need to shrink, because the flex-shrink value of item-3 is 0, so the item-3 will not shrink, still displayed at 200px.
Item-1 reduction value =(2 200px/(2 200px + 3 800px + 0 200px)) \ * 400px = 57.14px;
Item-2 magnification value =(3 800px/(2 200px + 3 800px + 0 200px)) \ * 400px = 342.86px;
So, the final size of item-1 = 200px-57.14px = 142.86px;
item-2 size = 800px-342.86px = 457.14px;
item-3 size = 200px;