Detailed explanation of the calculation method of flex-grow and flex-shrink in flex layout

Detailed explanation of the calculation method of flex-grow and flex-shrink in flex layout

Flex(彈性布局) in CSS can flexibly control the layout of a web page. The width/height of items in a Flex layout are determined by three properties:
flex-basis , flex-grow , flex-shrink .

flex-basis

flex-basis determines how much space the item takes up on the main axis. Unless set using box-sizing , it will set the size of the content box, so you need to be careful when specifying the size of a flex item, as it is likely to include padding and borders.

You can specify a specific CSS size value for it, or you can specify the percentage of the parent element it occupies. Its default value is auto (automatically adjust the size according to the content)

<!-- demo-1 -->

  <div class="parent">
    <div class="child1">100px</div>
    <div class="child2">200px</div>
  </div>
  <div class="parent">
    <div class="child1">10%</div>
    <div class="child2">20%</div>
  </div>
  <div class="parent">
    <div class="child1">30%</div>
    <div class="child2">auto</div>
  </div>

  <style>
    .parent {
      width: 500px;
      display: flex;
      margin-bottom: 15px;
      text-align: center;
      background-color: #eeeeee;
    }

    /** Pixel value */
    .parent:nth-child(1) .child1 {
      flex-basis: 100px;
      background-color: #356969
    }
    .parent:nth-child(1) .child2 {
      flex-basis: 200px;
      background-color: #369925;
    }

    /** Percentage */
    .parent:nth-child(2) .child1 {
      flex-basis: 10%;
      background-color: #356969
    }
    .parent:nth-child(2) .child2 {
      flex-basis: 20%;
      background-color: #369925;
    }

    /** automatic*/
    .parent:nth-child(3) .child1 {
      flex-basis: 30%;
      background-color: #356969
    }
    .parent:nth-child(3) .child2 {
      flex-basis: auto;
      background-color: #369925;
    }
  </style> 

flex-grow

flex-grow sets the scale of the item when there is remaining space in the flex container (the size of the flex container minus the sum of the sizes of all flex items). Its default value is 0 (it will not be enlarged even if there is remaining space). If all items have the same flex-grow property value, they will share the remaining space equally, otherwise, they will be distributed according to the ratios defined by the different property values.

For example, if the main axis length is 600px, item 1 occupies 50px, item 2 occupies 100px, and item 3 occupies 150px, the remaining space is: 600px - (50px + 100px + 150px) = 300px

If the flex-grow property value of each item is the same (for example, all are 1), all items are allocated the same remaining space:
- Item 1: 300px * (1 / (1 + 1 + 1)) = 100px;
- Item 2: 300px * (1 / (1 + 1 + 1)) = 100px;
- Item 3: 300px * (1 / (1 + 1 + 1)) = 100px;

  <!-- demo-2 -->

  <div class="parent">
    <div class="child1">50px + 100px</div>
    <div class="child2">100px + 100px</div>
    <div class="child3">150px + 100px</div>
  </div>

  <style>
    .parent {
      width: 600px;
      display: flex;
      text-align: center;
      color: #eee;
    }

    .child1 {
      flex-basis: 50px;
      flex-grow: 1;
      background-color: #0066CC;
    } 

    .child2 {
      flex-basis: 100px;
      flex-grow: 1;
      background-color: #009900;
    }

    .child3 {
      flex-basis: 150px;
      flex-grow: 1;
      background-color: #CC3300;
    }
  </style> 

Assume that the value of the flex-grow property of each item is not the same, for example, item 1 is 1, item 2 is 2, and item 3 is 3, then the remaining space allocated to them is:
- Item 1: 300px * (1 / (1 + 2 + 3)) = 50px;
- Item 2: 300px * (2 / (1 + 2 + 3)) = 100px;
- Item 3: 300px * (3 / (1 + 2 + 3)) = 150px;

  <!-- demo-3 -->

  <div class="parent">
    <div class="child1">50px + 50px</div>
    <div class="child2">100px + 100px</div>
    <div class="child3">150px + 150px</div>
  </div>

  <style>
    .parent {
      width: 600px;
      display: flex;
      text-align: center;
      color: #eee;
    }

    .child1 {
      flex-basis: 50px;
      flex-grow: 1;
      background-color: #0066CC;
    } 

    .child2 {
      flex-basis: 100px;
      flex-grow: 2;
      background-color: #009900;
    }

    .child3 {
      flex-basis: 150px;
      flex-grow: 3;
      background-color: #CC3300;
    }
  </style>

What if the attribute value is a decimal? There are two situations here:
1. If the sum of the flex-gorw attribute values ​​of all flex items is greater than 1, the calculation is still performed in the above way;
2. The sum of the flex-gorw attribute values ​​of all flex items is less than 1, and the base value is calculated as 1. For example, if item 1 is 0.2, item 2 is 0.3, and item 3 is 0.4, then the remaining space allocated to them is:
- Item 1: 300px * (0.2 / 1) = 60px;
- Item 2: 300px * (0.3 / 1) = 90px;
- Item 3: 300px * (0.4 / 1) = 120px;

 <!-- demo-4 -->

  <div class="parent">
    <div class="child1">50px + 60px</div>
    <div class="child2">100px + 90px</div>
    <div class="child3">150px + 120px</div>
  </div>

  <style>
    .parent {
      width: 600px;
      display: flex;
      text-align: center;
      color: #eee;
    }

    .child1 {
      flex-basis: 50px;
      flex-grow: 0.2;
      background-color: #0066CC;
    } 

    .child2 {
      flex-basis: 100px;
      flex-grow: 0.3;
      background-color: #009900;
    }

    .child3 {
      flex-basis: 150px;
      flex-grow: 0.4;
      background-color: #CC3300;
    }

flex-shrink

flex-shrink sets the magnification ratio of the item when there is insufficient space in the flex container. Its default value is 1 (the item will shrink when there is insufficient space).

The calculation method of flex-shrink is slightly different from flex-grow. There are two factors that affect how much the flex item should shrink. One is the value of the flex-shrink property, and the other is the size of the flex item itself. They shrink according to their respective weights. For example:

The main axis length is 600px, item 1 occupies 100px, item 2 occupies 300px, item 3 occupies 500px, and flex-shrink attribute values ​​of each item are 1, 3, and 2 respectively. The total weight is 100px 1 + 300px 3 + 500px *2 = 2000px, and the weights of each item are:
- Item 1: (100px * 1) / 2000px = 0.05;
- Item 2: (300px * 3) / 2000px = 0.45;
- Item 3: (500px * 2) / 2000px = 0.50;
The overflow space length is: 100px + 300px + 500px - 600px = 300px;
Then minify each project separately:
- Item 1: 300px * 0.05 = 15px;
- Item 2: 300px * 0.45 = 135px;
- Item 3: 300px * 0.50 = 150px;

 <!-- demo-5 -->

  <div class="parent">
    <div class="child1">100px - 15px</div>
    <div class="child2">300px - 135px</div>
    <div class="child3">500px - 150px</div>
  </div>
  <style>
    .parent {
      width: 600px;
      display: flex;
      text-align: center;
      color: #eee;
    }

    .child1 {
      flex-basis: 100px;
      flex-shrink: 1;
      background-color: #0066CC;
    } 

    .child2 {
      flex-basis: 300px;
      flex-shrink: 3;
      background-color: #009900;
    }

    .child3 {
      flex-basis: 500px;
      flex-shrink: 2;
      background-color: #CC3300;
    }
  </style> 

Similarly, when the value of flex-shrink is a decimal, there are two cases:
1. If the sum of the flex-shrink property values ​​of all flex items is greater than 1, the calculation is still performed in the above way;
2. The sum of the flex-shrink property values ​​of all flex items is less than 1, and only part of the overflow space is shrunk. For example, if item 1 is 0.1, item 2 is 0.3, and item 3 is 0.2, the total shrinkage space is:
300px * (0.1 + 0.3 + 0.2) = 180px
The weight calculation method for each item is the same, and each item is scaled down separately:
- Item 1: 180px * 0.05 = 9px;
- Item 2: 180px * 0.45 = 81px;
- Item 3: 180px * 0.50 = 90px;

 <!-- demo-6 -->

  <div class="parent">
    <div class="child1">100px - 9px</div>
    <div class="child2">300px - 135px</div>
    <div class="child3">500px - 90px</div>
  </div>

    <style>
    .parent {
      width: 600px;
      display: flex;
      text-align: center;
      color: #eee;
    }

    .child1 {
      flex-basis: 100px;
      flex-shrink: 0.1;
      background-color: #0066CC;
    } 

    .child2 {
      flex-basis: 300px;
      flex-shrink: 0.3;
      background-color: #009900;
    }

    .child3 {
      flex-basis: 500px;
      flex-shrink: 0.2;
      background-color: #CC3300;
    }
  </style> 

Since only a portion of the overflow space is contracted, the total width of the elements within the div actually exceeds the width of the div.

The above is a brief introduction to the calculation method of flex-grow and flex-shrink in flex layout.

The code in this blog has been synchronized to Github

References:
[1]. MDN documentation https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-basis
[2]. MDN documentation https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-grow
[3]. MDN documentation https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-shrink

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

<<:  Difference between HTML4 and HTML5: How to add focus implementation code to an input

>>:  Native JS to achieve sliding button effect

Recommend

Analyzing the MySql CURRENT_TIMESTAMP function by example

When creating a time field DEFAULT CURRENT_TIMEST...

Docker container from entry to obsession (recommended)

1. What is Docker? Everyone knows about virtual m...

CSS3 clear float method example

1. Purpose Through this article, everyone can und...

Detailed explanation of Vue filters

<body> <div id="root"> <...

Summary of MySQL database and table sharding

During project development, our database data is ...

Tutorial on installing DAMO database on Centos7

1. Preparation After installing the Linux operati...

React internationalization react-i18next detailed explanation

Introduction react-i18next is a powerful internat...

Implementation of MySQL custom list sorting by specified field

Problem Description As we all know, the SQL to so...

Detailed steps to install the NERDTree plugin in Vim on Ubuntu

NERDTree is a file system browser for Vim. With t...

Form submission page refresh does not jump

1. Design source code Copy code The code is as fol...

Tips for implementing list loop scrolling based on jQuery (super simple)

I saw a good idea and recorded it. I have used jQ...

How to solve the mysql ERROR 1045 (28000)-- Access denied for user problem

Problem description (the following discussion is ...

Implementation of MySQL multi-version concurrency control MVCC

Transaction isolation level settings set global t...