1. The Flex layout
The Flex attribute is a short term for flex-grow, flex-shrink, and flex-basis. The default value is 0, 1 Auto
Any container can be used for layout in Flex, and Flex occurs in the layout relationship between the parent container and the child container. What is the relationship between the parent container and the child container, and how to calculate the space occupied by the child container? How do you do elastic layouts?
To solve the above problem, it is necessary to know how to calculate flex-grow and flex-shrink. How does flex-basis differ from width?
Next, we first put forward two concepts: surplus space and overflow space, which will be explained later.
2. flex-grow
The flex-grow property on MDN is defined as:
Define the stretch factor for the flex-item. Default is 0.”
The traditional layout is the child container in the parent container layout from left to right, apply flex layout, then the parent container must set display: flex, child container to “occupy” and “divide” the space of the parent container, how to occupy, partition strategy is the elastic layout strategy. Here comes the concept of “surplus space” :
How much space does the child have left on the parent’s main axis? The amount of space that can be carved up is called the remaining space.
Text is always abstract, so an example will help you understand the remaining space. Here is the code:
HTML code:
<div class="container">
<div class="item a">
<p>A</p>
<p> width:100</p>
</div>
<div class="item b">
<p>B</p>
<p> width:150</p>
</div>
<div class="item c">
<p>C</p>
<p> width:100</p>
</div>
</div>
Copy the code
The CSS code:
.container {
margin:10px;
display: flex;
width: 500px;
height: 200px;
background-color: #eee;
color: # 666;
text-align: center;
}
.item {
height: 100px;
}
.item p {
margin: 0;
}
.a{
width: 100px;
background-color:#ff4466;
}
.b{
width: 150px;
background-color:#42b983;
}
.c{
width: 100px;
background-color:#61dafb;
}
Copy the code
The display looks like this (the last box is the annotation of the screenshot, not the displayed effect) :
A picture is worth a thousand words, so if you look at this picture, you know what residual space is.
The parent container has so much free space in its main axis, how can the child divide up the free space to achieve elastic effect?
This is where the flex-grow property is used. Flex-grow defines the percentage of the remaining space allocated to the child container. The default is 0, meaning that if there is any remaining space, it will not be allocated.
For the flex-grow example, change the above example to the following code:
HTML code (code only adds flex-grow instructions, no other structural changes) :
<div class="container">
<div class="item a">
<p>A</p>
<p> width:100</p>
<p>flex-grow:1</p>
</div>
<div class="item b">
<p>B</p>
<p> width:150</p>
<p>flex-grow:2</p>
</div>
<div class="item c">
<p>C</p>
<p> width:100</p>
<p>flex-grow:3</p>
</div>
</div>
Copy the code
CSS code (added flex-grow to each child container) :
.container {
margin:10px;
display: flex;
width: 500px;
height: 200px;
background-color: #eee;
color: #666;
text-align: center;
}
.item {
height: 100px;
p {
margin: 0;
}
}
.a{
width: 100px;
flex-grow:1;
background-color:#ff4466;
}
.b{
width: 150px;
flex-grow:2;
background-color:#42b983;
}
.c{
width: 100px;
flex-grow:3;
background-color:#61dafb;
}
Copy the code
The results are as follows:
Initially, we found that the total width of the children was only 350px and the width of the parent was 500px, so the remaining space was 150px. When flex-grow is set, child containers A, B, and C “divide” the remaining space based on their own flex-grow.
The summary here is that the flex-grow property determines how much space the child takes up with the parent.
The calculation method is as follows:
- Remaining space: x
- Suppose you have three Flex item elements with flex-grow values a, B, and C
- The surplus space of each element can be allocated as follows: a/(a + b + c) * x, b/(a + b + c) * x, c/(a + b + c) * x
Take A as an example to illustrate: THE proportion of A to the remaining space: 1/(1+2+3) = 1/6, then the 150*1/6 that A “divides” =25, the actual width is 100+25=125.
Is it possible to set flex-grow to a value less than 1 and have the sum of flex-grow also be less than 1? Simply set the denominator (the sum of flex-grow) to 1.
3. flex-shrink
With flex-grow, we know that the child container is set to flex-grow and can be stretched. So what happens when the subcontainer gets compressed? Consider a case where the child is larger than the parent, even if flex-grow is set, but there is no space left, no space is allocated. There are two options: line feed and compression. Since Flex doesn’t break lines by default, how and by how much do you compress it? This is where the Flex-Shrink attribute is required.
The flex-Shrink attribute is defined on MDN as follows:
Specifies a contraction rule for Flex elements, with a default value of 1
At this point, the concept of surplus space is transformed into “overflow space”
Calculation method:
- Width of three Flex item elements: w1, w2, w3
- Flex -shrink for three Flex item elements: a, B, c
- Calculate the total compression weight: sum = A * w1 + B * w2 + C * w3
- Calculate the compression ratio of each element: S1 = A * w1 / sum, S2 = B * w2 / sum, S3 = C * w3 / sum
- Calculate the width of each element: width – compression ratio * overflow space
For example:
<div class="container">
<div class="item a">
<p>A</p>
<p> width:300</p>
<p>flex-shrink: 1</p>
</div>
<div class="item b">
<p>B</p>
<p> width:150</p>
<p>flex-shrink: 2</p>
</div>
<div class="item c">
<p>C</p>
<p> width:200</p>
<p>flex-shrink: 3</p>
</div>
</div>
Copy the code
.container {
margin:10px;
display: flex;
width: 500px;
height: 200px;
background-color: #eee;
color: # 666;
text-align:center;
}
.item {
height: 100px;
}
.item p {
margin: 0;
}
.a{
width: 300px;
flex-grow: 1;
flex-shrink: 1;
background-color:#ff4466;
}
.b{
width: 150px;
flex-shrink: 2;
background-color:#42b983;
}
.c{
width: 200px;
flex-shrink: 3;
background-color:#61dafb;
}
Copy the code
Total compression: 300*1 + 150 * 2 + 200 * 3 = 1200 COMPRESSION ratio of A: 300* 1/1200 = 0.25 compression value of A: 150 * 0.25 = 37.5a Actual width: 300 minus 37.5 = 262.5
The results are as follows:
Also, if the flex-shrink sum is less than 1? So the calculation of the overflow space (the sum of contractions) has changed. For example, if shrink is set to 0.1, 0.2, 0.3, and the original overflow space is 200, the actual overflow space is 200 * (0.1 + 0.2 + 0.3) / 1 = 120.
Note: If the child does not exceed the parent, setting Flex-shrink does not work
4. flex-basis
MDN definition: specifies the initial size of a Flex element along the main axis
Once a Flex item is placed in a Flex container, there is no guarantee that it will be displayed at the size set by Flex-basis. The browser calculates whether the spindle has free space based on flex-basis. Max-width, min-width, width, box, and min-width
For example:
<div class="container">
<div class="item a">A</div>
<div class="item b">B</div>
<div class="item c">C</div>
</div>
Copy the code
.container {
margin:10px;
display: flex;
width: 500px;
height: 200px;
background-color: #eee;
text-align: center;
line-height: 100px;
color: # 666;
}
.item {
width: 100px;
height: 100px;
}
.a{
flex-basis: 200px;
background-color:#ff4466;
}
.b{
max-width: 50px;
flex-basis: 150px;
background-color:#42b983;
}
.c{
background-color:#61dafb;
}
Copy the code
The results are as follows:
max-width/min-width > flex-basis > width > box
5. Application scenarios
- A very common layout: when the height of the content area is insufficient, the footer still needs to be fixed at the bottom. At this point, we can give Main flex-grow: 1 to automatically fill the remaining space.
2. When we were developing a common form component, we used flex layout so that the input field filled up the remaining space.
In most cases, we don’t want elements to be compressed, so flex-shrink is usually set to 0.
6. Summary
Finally, we need to note:
- If the flex items total exceeds the Flex container, it is compressed according to the Flex-shrink setting
- If there is free space, the actual width of the child container depends on the flex-grow setting if flex-grow is set. If flex-grow is not set, the actual width is displayed as flex-basis
References:
-
Developer.mozilla.org/zh-CN/docs/…
-
Developer.mozilla.org/zh-CN/docs/…
-
Developer.mozilla.org/zh-CN/docs/…
-
www.ruanyifeng.com/blog/2015/0…
-
Gedd. Ski/post/the – di…
-
zhuanlan.zhihu.com/p/24372279