Key points of this article:

  • What does flex mean when it sets single, double, and triple values in the Flex layout?
  • How to shrink negative space in Flex layouts
  • How to allocate extra space in flex layout (Flex-grow)
  • How do flex-basis and Flex-grow work together to allocate space

example

First define the structure:

<div class="list"> <div class="item singleValue"> <div class="item singleValue" "> <div class="list"> <div class="item doubleValue"> <div class="item doubleValue"> <div class="item doubleValue" <div class="item doubleValue"> </div> </div>Copy the code

Basic style:

.list {
  display: flex;
  box-sizing: border-box;
  width: 300px;
  margin: 10px;
}

.item {
  background: pink;
}
.item:nth-child(2) {
  background: lightblue;
}
Copy the code

Flex single value

When there are no units, Flex sets a single value, equivalent to flex-grow, to indicate the elastic ratio of the children:

.singlevalue {/* singleValue is equivalent to flex-grow, defining the stretch factor of flex item */ flex: 1; }.singleValue:first-child {/* Equivalent to flex: 2 */ flex-grow: 2; }Copy the code

Effect:

.singlevalue :last-child {/* singleValue with unit, equivalent to flex-basis */ /* flex: 75px; */ flex-basis: 75px; }Copy the code

Effect:

I found that the third subitem was not 75px as expected, but I’ll talk about that later.

Double value or triple value

Double values the first is flex-grow and the second, if any, is flex-basis

.doubleValue {
  flex: 1 300px;
}
Copy the code

The total width of the List is 300 and each subitem is 300px, which is far beyond the range of flex’s elastic box, so the subitem width will be automatically adjusted according to Flex’s algorithm as follows:

Set three values:

.doubleValue:first-child {
  flex: 1 0 300px;
}
Copy the code

Is equal to:

.doubleValue:first-child {
 flex-shrink: 0; 
}
Copy the code

In other words, if the first value is flex-grow and the second has no unit, it is flex-shrink. Three values, respectively is the flex – turns up | flex – the shrink | flex – basis.

The effect is as follows:

How flex-shrink is calculated

Flex-shrink comes in handy when the sum of the widths we set for the children is greater than the width of the parent element.

By default, the flex-shrink value for each subitem is 1. All sub-items will be proportionally automatic compression, save worry and effort.

In actual projects, the most common flexing shrink value might be either 0 or 1. The default is 1. If you don’t want subitems to be automatically compressed, set it to 0.

In the official definition of Flex-shrink, I found that the value of Flex-shrink can range from zero to infinity, which is non-negative. So how does Flex-shrink calculate the compressed value?

I’ll change the upper double value class to:

.doubleValue {
  flex-basis: 150px;
}

.doubleValue:first-child {
  flex-basis: 300px;
  flex-shrink: 2;
}
Copy the code

We get three 100px wide subterms:

In drafts.csswg.org/css-flexbox… The flex-shrink compression factor is defined as:

… which determines how much the flex item will shrink relative to the rest of the flex items

Half understand. We don’t actually need to know how Flex-shrink allocates space to use Flex layouts; the browser does everything for us.

In my Day 24: flex – the shrink calculation | SamanthaMing.com to find an algorithm:

Validation:

Calculate the shrunk space:

Shrunk space = (300 +150 + 150) – 300 = 300

There is 300px extra space that needs to be compressed.

Calculate the shrink thewire

total shrink scaled width = 300 * 2 + 150 * 1 + 150 * 1 = 900

First child Shrink ratio = 300 * 2/900 = 0.666…

Nth-child(2/3) shrink ratio = 150 * 1/900 = 0.166…

Calculate the new width

First child new width = 300[flex-basis value] – (300[shrunk space]* 0.666..) first child new width = 300[flex-basis value] – (300[shrunk space]* 0.666..) = 100px

Nth-child(2/3) new width = 150 – 300 * 0.166… = 100px

Hence the three equally divided subterms:

exceptions

I wanted to make the subitem look nice, so I added the padding:

.item { padding: 10px; background: pink; }

Look what I got:

To:

.item {
  box-sizing: border-box;
  padding: 10px;
  background: pink;
}
Copy the code

The above formula works.

flex-grow

Flex-grow Settings are necessary when the sum of the child widths is less than the parent element widths.

Still use www.samanthaming.com/flexbox30/2… To show how Flex-Grow allocates free space:

.doubleValue {
  flex-grow: 1;
  flex-basis: 50px;
}

.doubleValue:first-child {
  flex-grow: 2;
  flex-basis: 100px;
}
Copy the code

I get 150px, 75px, 75px:

Free space to be allocated = 300 – (100 + 50 + 50) = 100px

Flex-grow total = 2 + 1 + 1 = 4

The amount of extra space that first-child can be allocated = 100 * 2/4

The amount of space that other subterms can be allocated is equal to 50 times 1/4

The final width of first-Child: 100 + 100 * 2/4 = 150px

Final width of other subterms: 50 + 100*1/4 = 75px

Take a look back at the flex-basis Settings

.singleValue {
  flex: 1;
}
.singleValue:first-child {
  flex-grow: 2;
}
.singleValue:last-child {
  flex-basis: 75px;
}
Copy the code

112.5px, 56.25px and 131.25px are obtained respectively:

The first two subitems are proportionally allocated, and the third adds the flex-basis setting on a proportional basis, so you get the sum of the space automatically allocated when flex-grow is 1 + Flex-basis.

Then replace it with:

.singleValue {
  flex: 1;
  flex-basis: 10px;
}
.singleValue:first-child {
  flex-grow: 2;
}
.singleValue:last-child {
  flex-basis: 20px;
}
Copy the code

Now, the width of the three subterms is 140px, 75px, and 85px.

Looking back at the definition of flex-basis:

Flex-basis specifies the initial size of the Flex element in the main axis direction. This property determines the size of the Flex element’s content-box if you do not use box-sizing to change the box model.

The default flex-basis value is Auto.