The Flex layout scheme is well suited for applying multi-column contour layout scenarios. This article will delve into flex-grow, Flex-shrink, and Flex-basis attributes. Fully understanding how these attributes work with growing and shrinking Flex child elements is key to mastering Flex layouts.

flexgrammar

The flex-grow, flex-shrink, and Flex-basis attributes are applied to flex child elements and control the following aspects of a Flex child element:

  • Flex-grow: How much space is left for this Flex child element?
  • Flex-shrink: How much space is shrunk from this Flex child element?
  • Flex-basis: What is the original size of a Flex child element before it is expanded and contracted?

flex-basis

Q1: How does the browser determineflexThe size of the child element

The flex child element space can be determined using the Flex-basis attribute, which can be set to the following value (for example, the main axis horizontal):

flex-basis: <width> | content;
where <width> = auto | <length> | <percentage> | min-content | max-content | fit-content | fit-content(<length-percentage>)
Copy the code
  1. flex-basisA value ofauto:
    • If you set upwidth.flexThe original size of the child element iswidth;
    • Otherwise,flexThe original size of the child element ismax-content.
Div :nth-child(1){background-color: red; background-color: red; background-color: red; flex-basis: auto; width: 100px; } /* set width to max-content*/. Test > div:nth-child(1){background-color: red; flex-basis: auto; }Copy the code
  1. flex-basisA value of<length> | <percentage>(XXpx.XX%) will be used<length> | <percentage>As aflexThe original size of the child element.
Div :nth-child(1){background-color: red; background-color: red; background-color: red; flex-basis: 100px; } background-color: red; background-color: red; background-color: red; background-color: red; background-color: red; background-color: red; background-color: red; flex-basis: 100px; width:200px; }Copy the code

When an element is set to both Flex-basis (in addition to the value auto) and width, flex-basis has a higher priority.

  1. flex-basisIs 0, thenflexThe original size of the child element ismin-content.

Q2: The key word ismin-contentandmax-contentThe meaning of?

Literally, it refers to minimum content space and maximum content space:

  1. min-content: Wrap all text
            .test > div:nth-child(1){
                background-color: red;
                flex-basis: auto;
                width: min-content;
            }
Copy the code

2. Max-content: No line wrapping. If the Flex container is too narrow, it will cause the container to overflow

            .test > div:nth-child(1){
                background-color: red;
                flex-basis: auto;
                width: max-content;
            }
Copy the code

flex-grow

Q1:flex-growWhich part of space is the remaining space in

A Flex layout has Flex containers and Flex children. The Flex children are contained in the Flex container. When the sum of the original sizes of the Flex children on the main axis is less than the size of the Flex container, there will be extra space in the Flex container that has not been filled.


Q2: How to allocate the unallocated remaining space?

If you want to use all the space, how should you allocate the remaining space? The way the remaining space is allocated should be highly flexible. After all, not every designer has the same space allocation strategy. Flex-grow determines how the remaining space is allocated, and since each Flex child element can have a different flex-grow value, you can use the flex-grow value as a space allocation weight to determine how much remaining space that child element gets.

For example,

If the Flex container is 800px and the Flex child elements are div1, div2, and Div3, which are 100px, 200px, and 300px respectively, then the remaining space is 200px(800-100-200-300). Suppose three flex have flex-grow values of 1,1,2. The remaining space is allocated as follows:


d i v 1 ( The remaining space ) = 200 p x ( 1 / ( 1 + 1 + 2 ) ) = 50 p x Div1 (free space)=200px*(1/(1+1+2))=50px

d i v 2 ( The remaining space ) = 200 p x ( 1 / ( 1 + 1 + 2 ) ) = 50 p x Div2 (free space)=200px*(1/(1+1+2))=50px

d i v 3 ( The remaining space ) = 200 p x ( 2 / ( 1 + 1 + 2 ) ) = 100 p x Div3 (free space)=200px*(2/(1+1+2))=100px

The idea should be easy to understand, but flex-grow determines the weight of the remaining space allocation. Therefore, the total space of Flex child elements is:


d i v 1 ( Total space ) = 100 p x + 50 p x = 150 p x Div1 (total space)=100px+50px=150px

d i v 2 ( Total space ) = 200 p x + 50 p x = 250 p x Div2 (total space)=200px+50px=250px

d i v 3 ( Total space ) = 300 p x + 100 p x = 400 p x Div3 (total space)=300px+100px=400px

Let’s keep thinking, what if I don’t want to allocate all of my remaining space, but I want to allocate 40% of my remaining space (80px)? Can you specify the total amount of free space allocated without adding an extra parameter? If the total flex-grow of each child element is less than 1, the remaining space is not fully allocated, and the total flex-grow of each child element is the percentage of the remaining space allocated.

For example,

If the Flex container is 800px and the Flex child elements are div1, div2, and Div3, which are 100px, 200px, and 300px respectively, then the remaining space is 200px(800-100-200-300). Suppose three Flex have flex-grow values of 0.1,0.1, and 0.2. The remaining space is allocated as follows:


d i v 1 ( The remaining space ) = 200 p x ( 0.1 + 0.1 + 0.2 ) ( 1 / ( 1 + 1 + 2 ) ) = 20 p x Div1 (free space)=200px*(0.1+0.1+0.2)*(1/(1+1+2))=20px

d i v 2 ( The remaining space ) = 200 p x ( 0.1 + 0.1 + 0.2 ) ( 1 / ( 1 + 1 + 2 ) ) = 20 p x Div2 (free space)=200px*(0.1+0.1+0.2)*(1/(1+1+2))=20px

d i v 3 ( The remaining space ) = 200 p x ( 0.1 + 0.1 + 0.2 ) ( 2 / ( 1 + 1 + 2 ) ) = 40 p x Div3 (free space)=200px*(0.1+0.1+0.2)*(2/(1+1+2))=40px

d i v 1 ( Total space ) = 100 p x + 20 p x = 120 p x Div1 (total space)=100px+20px=120px

d i v 2 ( Total space ) = 200 p x + 20 p x = 220 p x Div2 (total space)=200px+20px=220px

d i v 3 ( Total space ) = 300 p x + 40 p x = 340 p x Div3 (total space)=300px+40px=340px

The remaining space is allocated = 200 p x ( 1 0.1 0.1 0.2 ) = 200 p x 0.6 = 120 p x Free space after allocation =200px*(1-0.1-0.1-0.2)=200px*0.6=120px

Moving on, a very common layout is to divide the space of a Flex container equally for each Flex child element. Does that mean you need to calculate exactly how much space each Flex child element should have? What if all the space left is not enough for the Flex child element space to be equally divided?

The answer is clearly no. You just need to complete the following two steps:

  1. Set all theflexChild elementsflex-basisValue is 0To tell the browserflexThe original size of the child element is treated as 0, that is, all space is free space;
  2. Set all theflexChild elementsflex-growThe value is 1(the same is ok)To tell the browserflexChild elements divide the remaining space evenly.

flex-shrink

The Flex-shrink attribute specifies the Flex shrink value, which is how much flex child elements shrink relative to other Flex child elements.

Q1: When do Flex child elements shrink?

Obviously, when the sum of the original sizes of flex child elements is less than the flex container, a contraction occurs. Because if the element does not shrink, it must overflow.

Q2:flexWhat is the minimum space in which a child element can contract? Could you shorten it to 0px?

If the flex child element space shrinks to 0, the flex child element information cannot be represented. Therefore, when the browser sets the minimum search value width to min-content, that is, the width of the flex child element to use every opportunity to break the line.

Q3:flexHow do the child elements determine their respective shrink space?


Total shrinkage space = f l e x Sum of the original sizes of the child elements f l e x The container size Total shrunk space = Sum of original size of Flex child elements – Size of flex container

Think, if you were a designer, how would you arrange the shrinking space of each Flex child element?

For example, if the flex container is 300px and the flex child elements are div1, div2, and div3, which are 100px, 200px, and 300px respectively, assume that the flex-shrink values are 1,1,1.

Obviously, the total shrinkage space is:


Total shrinkage space =   ( 100 p x + 200 p x + 300 p x ) 300 p x = 300 p x Total shrinkage space =(100px + 200px +300px) -300px = 300px

Because the flex-shrink value is 1,1,1, is it similar to flex-grow allocating a 1:1:1 total shrink space, i.e. Div1, div2, and div3 all shrink 100px space? This allocation strategy directly causes div1 to shrink to 0px, but div3 is still 200px.

Instead of this crude allocation, browsers use a more equitable allocation, where flex child elements with more space should shrink more to ensure that flex child elements with less space are not too small. Therefore, the allocation scheme is weighted by multiplying the original size of the Flex child element by the Flex-shrink value:


f l e x The child element should contract the space = Total shrinkage space x ( f l e x The original size of the child element s h r i n k Value) / ( f l e x The original size of the child element s h r i n k Value) Flex subelement shrink space = Total shrink space × (Flex subelement original size *shrink value) /\sum (Flex subelement original size *shrink value)

Therefore, the contraction space allocation in the example is:


Total shrinkage space =   ( 100 p x + 200 p x + 300 p x ) 300 p x = 300 p x Total shrinkage space =(100px + 200px +300px) -300px = 300px

( f l e x The original size of the child element s h r i n k Value) = 1 100 + 1 200 + 1 300 = 600 \sum (flex child size *shrink value) = 1*100+1*200+1*300 = 600

d i v 1 ( Contracted space ) = 300 p x ( 1 100 ) ( 600 ) = 50 p x Div1 =300px*(1*100)*(600)=50px

d i v 2 ( Contracted space ) = 200 p x ( 1 200 ) ( 600 ) = 100 p x Div2 =200px*(1*200)*(600)=100px

d i v 3 ( Contracted space ) = 200 p x ( 1 300 ) ( 600 ) = 200 p x Div3 =200px*(1*300)*(600)=200px

Q4: What should I do if I don’t want to fully allocate the shrink spaceflex-shrinkValue?

Incomplete flex-shrink allocation results in overflow behavior, similar to flex-grow, if the sum of flex-shrink for each child element is less than 1, then the flex-shrink allocation is incomplete, and the sum of flex-shrink for each child element is the percentage of the allocated shrink space. I won’t go into detail here.

Q5: In the process of shrinking spaceflexChild element reachmin-contentHow does that affectflexSpace allocation?

The original size of the Flex child element is 100px with a min-content of 20px, but the flex child element should shrink by 100px, so the Flex child element will only shrink to 20px. Does the uncontracted 20px of this element affect the space of other Flex elements in the container?

For example, if the flex container is 300px and the flex child elements are div1, div2, and div3, which are 100px, 200px, and 300px respectively, assume that the flex-shrink values are 1,1,1, and min-content are 60px.

According to the calculation results of shrink space allocation in Q3, without considering min-content, DIV1, DIV2 and Div3 should shrink 50px,100px and 200px respectively. However, due to the influence of min-content, div1 can not shrink to 50px, can only shrink to 60px, the remaining 10px will be added to div2, DIV3 shrink the total space, and then by div2, Div3 according to Q3 shrink space allocation principle to calculate the final div2, DIV3 shrink allocation results.