Flex-basis, flex-grow and flex-shrink
In this topic we will three properties that will allow content to change it's size according to the size of the container. This will be useful for elements that change dinamically when the window is resized, or when viewing on a smaller screen.
We will start with the basic settings, that allows us to set a total size, how much each element can grow when possible, and how much they will shrink when needed.
Flex-basis: the initial value on the main-axis
Flex-basis is simple at first glance. It is the size at which the element will be placed in the main-axis. If flex-basis: 250px
, when flex is set to row it will be a 250px width, and if we change it to column it will be 250px height. Without flex-grow and flex-shrink it will break the content (if wrap is enabled) as soon as the container becomes too small for the set value.
Here, because of the restrictions on the size of the body (1000px), we won't be able to enlarge the content past 250px, but if this was a column, we could have the container stretching to fit the content.
Flex-grow: how much the element will grow when there is available space
With flex-grow we can define how much each element can grow given the available space. But this is a very powerful tool. The first thing to know is that it accepts unit-less number values., In other words, whe can assing a flex-grow: 2
to a element, without any units like pixels, em, rem or percentage.
If we define each one of the boxes as 100px and give the first box the property of flex-grow: 1
, it will take all availabe space and grow accordingly:
If we give every element a value of 1, they will have the same size:
The unit-less values are proportions in which the available space will be distributed. If we give the first box a value of 2 and the last box a value of 1, the first box will grow twice as much as the last box. Its growth is 2:1.
When the screen shrinks below the sum of the boxes, it will break and wrap. The new line or column will the be distributed accordingly to the element residing there.
We can also control how much the elements will grow by setting the property max-width which will accept any normal values and units. For instance, if we set max-width: 250px
to the boxes, they will only grow so much, even after wraping. In this example we will assign flex-grow: 1
to the last box, and the max-width: 300px
. Note the empty space on the right.
On the example above, since we set flex-basis: 200px
, the last box will shrink until it reaches the minimum width of 200px, and break into a new line, but it will only have a miximum of 250px.
Flex-shrink: the rate at which an element shrinks
Flex-shrink is similar to flex-grow. It controls the rate at which content will shrink when there's not enough available space. It also uses unit-less values as proportions, and can be set with a min-width
to prevent them from disappearing.
In the example below, we set flex-basis:250px; min-width: 50px
and the shrink values of 1 to the second box and 2 to the third box. That way, the third box will shrink twice as fast as the second box, but no less than 50px. The other boxes won't shrink at all.
One trick that can be used with flex-shrink
is to set the values for all the content at least 1, so that they can shrink when the container is resized. If there's one element that should not be shrunked, we can then set its value to zero. That way, they will remain the size defined by flex-basis.
That same trick can be used if setting the size for all the elements ends in a bigger value than the container. For instance, if we have a screen that is 1000px wide, and four elements with a flex-basis: 250px
, they will not be at their largest size. If one of those elements needs to be 250px, then we can set flex-shrink: 0
to ensure it won't reduce in size.
Flex: shorthand for grow, shrink and basis
All of the properties we've seen in this section can be passed in a single line using the flex:
property. If we want to pass all three values, then the order would be: felx-growth, flex-shrink and flex-basis. considering an element of width of 250px, with a growth rate of 1 and shrink rate of 2, the syntax would be flex: 1 2 250px;
.
We can also pass less values, with flex: 1 2
only carrying values for growth and shrink, and flex: 1 250px
carrying values for growth and basis. If there is a value with a unit, than it will be considered the basis.