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 canflex-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.
- When it says flexible item this means it only works on flexbox children—unlike width.
- The word is length not width which is determined by the
flex-direction
property. The default value isrow
which means flex-items are laid out horizontally from L to R so in this case the length will be the width. However whenflex-direction
is set tocolumn
this length will it’s height, not width. - 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
andflex-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 aswidth
in a flex row (orheight
in a column). You can use them interchangeably, butflex-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.
-
See MDN on content ↩︎
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