skip navigation

Flexbox 3

The properties flex, flex-grow, flex-shrink and flex-basis are all applied to the child elements of a flex container.

flex

The flex property is shorthand for the other 3. If not set then default values are used. These are:

.flex-item {
    flex: 0 1 auto;
}

which is the equivalent to:

.flex-item {
    flex-grow: 0;
    flex-shrink: 1;
    flex-basis: auto;
}

However the flex property can take just 1 or 2 values too:

.flex-item {
    flex: 1;
}

If a single value is in units such as flex: 10em or flex: 400px or flex: min-content it can only apply to flex-basis.

If the value is unitless, such as flex: 1, it applies to flex-grow. Two unitless values means the first is flex-grow and the second is flex-shrink.

To understand these properties the first thing is to remember is that flex-items, the direct child elements of a flex-container, are flexible. That means that even if they have a fixed width set in pixels they can still try to shrink or grow to fill their container.

It’s also worth noting that they tend to work together. If a flex-item is given a width value of say 600px it will try to be 600 pixels wide but if there is not room because of the other flex-items AND flex-shrink is set to it’s default value of 1 it will shrink down to fit in the container. Because they work together in this way it’s often recommended to use the shorthand flex property so all 3 can be set on one line.

The flex property is about how much shrinking and growing takes place. However content is king in the flexbox world. Text will take up as much space as it can at first.

The way to think about this is to start with empty boxes (flex items in a flex containter).

Let’s look at each of these in turn.

flex-grow

The flex-grow property will only do something where there is extra space in the flex container.

The default value for flex-grow is zero which means flex items do not grow beyond the size they need. Usually this size is the size of the longest line of text or largest image or other element. On an empty flexbox this default value means an empty item will disappear altogether, it will have no width because it doesn’t need any. Changing flex-grow to a value other than zero will allow the flex item to grow.

If a flex-item is given flex-grow: 0.5 it will try to grow so as to take up half of the width of it’s container. The word try means it won’t override it’s sibling flex items at any cost. If there are 3 other items (so 4 in all) also set to flex-grow: 0.5 it’s impossible for them to all take up half the space so they’ll be forced to only take up a quarter of the space instead.

In short:

  • flex-grow: 0 means it won’t grow at all and only uses the minimum space it can
  • flex-grow: 0.1 means it will take up 10% of the size of the container, if it can.
  • flex-grow: 1 means it will take up the entire width, if it can.

Values above 1 are fine. They will be ratios between the different items. If one item has a value of 5 and the other a value of 10 the one of 10 will take up twice as much space as the other … if it can.

All 3 set to flex-grow: 0 (the default)

flex-shrink

The flex-shrink property will only do something where there is not enough space in the flex container for each item to be at their optimum size.

This is the opposite of flex-grow but unlike that the default value is set to 1. This means a flex-item will shrink down to as small as it can, which means as small as the shortest line or item.

When flex-items do not have enough room to fit inside their parent element they will shrink down to fit. If they are all left with their default value of flex-shrink: 1 they will all shrink by the same amount.

According to W3 Schools:

The flex-shrink property specifies how the item will shrink relative to the rest of the flexible items inside the same container.

So if one flex-item had flex-shrink set to 3 and the other items were left a the default of 1 it would shrink 3 times as much as the other items. So this number is relative to the other values.

When set to flex-shrink: 0 this means it does not shrink at all. It will even overflow it’s container if necessary. It’s flexability has been removed.

flex-basis

This is often thought of as width but it’s not. According to W3 Schools:

The flex-basis property specifies the initial length of a flexible item.

This simple statement covers a lot.

  1. When it says flexible item this means it only works on flexbox children—unlike width.
  2. The word is length not width which is determined by the flex-direction property. The default value is row which means flex-items are laid out horizontally from L to R so in this case the length will be the width. However when flex-direction is set to column this length will it’s height, not width.
  3. By initial length it means because these are flexible items this value is flexible. It can change according to the content and the values of flex-shrink and flex-grow. So this is different to a width setting.

Another thing to note with flex-basis is that if width is also set (when the flex-direction the default of row) the flex-basis size will take priority and the width value will be ignored. However if flex-grow is set that will take priority over the flex-basis value.

Another difference between width and flex-basis is that width can shrink down below the minimum width of the content.

flex-basis has a default value of auto. It can take values in CSS units: ems, percentage, pixels; intrinsic values min-content, max-content and fit-content. And addition to the spec is another keyword content which is similar to auto and sizes the flex item based on it’s content1.

Summary

A course by Josh Comeau says:

  • There are two important sizes when dealing with Flexbox: the minimum content size, and the hypothetical size.
  • The minimum content size is the smallest an item can get without its contents overflowing.
  • Setting width in a flex row (or height in a flex column) sets the hypothetical size. It isn’t a guarantee, it’s a suggestion.
  • flex-basis has the same effect as width in a flex row (or height in a column). You can use them interchangeably, but flex-basis will win if there’s a conflict.
  • flex-grow will allow a child to consume some or all of the excess space in the container. It has no effect if there isn’t any excess space.
  • flex-shrink will pick which item to consume space from, if the container is too small. It has no effect if there is excess space.
  • flex-shrink can’t shrink an item below its minimum content size. If all the items are below their minimum content size, this property has no effect.
View the CSS for this page

ul.flex-examples {
  list-style: none;
  margin: 0;
  padding: 0;
  /* column-count: 2; */
  /* display: flex; */
  /* flex-wrap: wrap; */
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 15px;
}
ul.flex-examples > li {
  display: table;
}
.flexsimple {
  display: flex;
  width: 350px;
  padding: .6em;
  /* margin: .5em 0 2em 0; */
  background: var(--MainBorderColor);
}

.flexsimple > div {
  padding: 1.2em;
  color: #333;

}

.flexsimple > div:first-child {
  background: lightblue;
}
.flexsimple > div:nth-child(2) {
  background: pink;
}
.flexsimple > div:nth-child(3) {
  background: lightgreen;
}
/* --- These are for the Jusify-content examples --- */

#fe1 #set1 {
  justify-content: flex-start;
}
#fe1 #set2 {
  justify-content: flex-end;
}

#fe1 #set3 {
  justify-content: center;
}

#fe1 #set4 {
  justify-content:space-around;
}
#fe1 #set5 {
  justify-content: space-between;
}


/* This is a way to center the content, the numbers, inside the little boxes --- */
#fe2 > li > .flexsimple > div {
  display: flex;
  justify-content: center;
  flex-direction: column;
  text-align: center;
}


#fe2 .flexsimple {
  height: 250px;
}

.set21 > div {
  height: auto;
}

#fe2 .set21 {
  align-items: stretch;
}
#fe2 .set22 {
  align-items: flex-start;
}
#fe2 .set23 {
  align-items: flex-end;
}
#fe2 .set24 {
  align-items: center;
}
#fe2 .set25 {
  align-items: baseline;
}
/* ====== For flex3.md ======== */

.flex-grow-05 div {
    flex-grow: 0.25