Understanding the difference between the flex and flex-grow properties
flex
is a shorthand property of flex-grow
, flex-shrink
and flex-basis
.
In this case, flex: 1
sets
flex-grow: 1
flex-shrink: 1
flex-basis: 0
(in old spec drafts it wasflex-basis: 0%
)
If you only use flex-grow: 1
, you will have
flex-grow: 1
flex-shrink: 1
flex-basis: auto
Then, the difference is that the flex base size will be 0 in the first case, so the flex items will have the same size after distributing free space.
In the second case each flex item will start with the size given by its content, and then will grow or shrink according to free space. Most probably the sizes will end up being different.
The difference between flex:1 and flex-grow:1
flex
The flex
property is a shorthand for setting:
flex-grow
flex-shrink
flex-basis
The flex: 1
rule is supposed to compute to this:
flex-grow: 1
flex-shrink: 1
flex-basis: 0
These values are defined in the spec. See section 7.1.1. Basic Values of flex
I say "supposed to compute" because, in IE11 and possibly other browsers, a unit of measure, such as px
or %
, is appended to the 0
value in flex-basis
. This can make a difference (example).
flex-grow
The flex-grow property (which distributes free space in the container among flex items), when declared by itself, leaves flex-shrink
and flex-basis
at their initial values.
So when you set flex-grow: 1
, the browser renders this:
flex-grow: 1
(overrides the default value, which is 0)flex-shrink: 1
(this is the default value)flex-basis: auto
(this is the default value)
The difference between flex: 1
and flex-grow: 1
Ultimately, the difference between flex: 1
and flex-grow: 1
is that the former sets flex-basis: 0
, and the latter keeps the default flex-basis: auto
.
For a complete explanation of the difference between flex-basis: 0
and flex-basis: auto
see this post:
- Make flex-grow expand items based on their original size
Your code example
The reason you're seeing a difference in your code is that flex-basis
controls height in a column-direction container.
In Chrome, with flex-basis: auto
, the height of the element is 450px (500px parent - 50px header). In other words, flex-grow
is free to distribute the free space.
With flex-basis: 0
, the height of the element is 0, and flex-grow
has no free space to distribute.
The height: 100%
on the child of the flex item is simply ignored because it isn't being applied properly, as explained in these posts:
- Working with the CSS
height
property and percentage values - Chrome / Safari not filling 100% height of flex parent
In reading the posts above you'll also understand why your code renders differently in Firefox, Safari, Edge and IE.
flex vs flex-grow producing different results
When you set only flex-grow
, the flex-basis
property remains unaffected. It still defaults to flex-basis: auto
.
When you use the flex
property, flex-basis
gets reset to 0.
So flex: 0
is shorthand for flex-grow: 0
and flex-basis: 0
. This means 0 width.
With flex-grow: 0
you still have flex-basis: auto
.
To understand the difference between flex-basis: 0
and flex-basis: auto
, see this post:
- Make flex-grow expand items based on their original size
What are the differences between flex-grow and width?
width
and flex-grow
are two entirely different CSS properties.
The width
property is used for defining the width of elements.
The flex-grow
property is used for distributing free space in a flex container. This property doesn't apply a specific length to an element, like the width
property. It simply allows a flex item to consume whatever space may be available.
Sometimes if I want one element to grow the rest of the space, I can either do
width: 100%
orflex-grow: 1
. How do I choose?
Yes, if there is one element in the row, width: 100%
and flex-grow: 1
may have the same effect (depending on padding
, border
and box-sizing
settings).
But what if there are two elements, and you want the second one to take the remaining space? With a sibling in the container, width: 100%
causes an overflow. I guess you can do something like this:
width: calc(100% - width of sibling);
But what if the sibling's width is dynamic or unknown? calc
is no longer an option.
The quick and easy solution is flex-grow: 1
.
While width
and flex-grow
are apples-to-oranges, width
and flex-basis
are apples-to-apples.
The flex-basis
property sets the initial main size of a flex item and is similar to width
.
- What are the differences between flex-basis and width?
For the differences between flex-basis
and flex-grow
see:
- flex-grow not sizing flex items as expected
What is the difference between the flex and height properties?
When you set an element to flex: 1
, that breaks down to:
flex-grow: 1
flex-shrink: 1
flex-basis: 0
In a column-direction container (like you have), the flex properties above apply vertically. This means that flex-basis
and height
are equivalent properties.
flex-basis = height (in a column-direction container)
There is an obvious difference between flex-basis: 0
and height: 100%
. It's the same difference as height: 0
and height: 100%
.
In your situation, where there is a .header
and a .footer
consuming 140px of vertical space, setting the middle item (.body
) to height: 100%
would normally cause an overflow.
But since an initial value of a flex container is flex-shrink: 1
, flex items are permitted to shrink, and this wouldn't happen. However, it's still sloppy and imprecise coding, in my view.
By setting .body
to flex: 1
, you're setting the height to 0
, but also allowing it to consume free height with flex-grow: 1
. I would say, in this case, that this solution is more efficient.
More details:
- What are the differences between flex-basis and width?
- § 7.1.1. Basic Values of
flex
Do I not understand the flex-grow property?
You have to specify a value for flex-basis
as well (not specifying this property causes behaviour similar to using the initial value, auto).
Add flex-basis: 0;
to both children or just set it with the shorthand:
.flex-item {
flex: 1; /* flex-basis is 0 if omitted */
}
.big {
flex-grow: 3;
}
http://codepen.io/anon/pen/JEcBa
Understanding flex-grow and flex-shrink when using flex-basis
Percentage lengths are relative to their containing blocks.
Therefore, if the flex container has a width of 200px, and the flex items are set to flex-basis: 50%
, then each item will resolve to 100px.
Of course, in flex layout, flex-basis
represents the initial main size or, the size before flex-grow
and flex-shrink
are applied.
You have flex-grow
disabled, so nothing happens there.
But you have flex-shrink
enabled, so the items will shrink below 100px when necessary to prevent an overflow of the container.
In this case, because all items are set to flex-shrink: 1
, they will shrink in equal proportion.
article { display: flex; width: 200px; border: 1px solid black;}
[one] > section { flex: 0 1 50px;}
[two] > section { flex: 0 1 50%;}
[three] > section { flex: 0 0 50%;}
/* non-essential demo styles */section { height: 50px; background-color: lightgreen; border: 1px solid #ccc; display: flex; justify-content: center; align-items: center; box-sizing: border-box;}
<p>container width 200px in all cases</p><article one> <section><span>50px</span></section> <section><span>50px</span></section> <section><span>50px</span></section> <section><span>50px</span></section></article>
<hr>
<p><code>flex-shrink</code> enabled</p>
<article two> <section><span>50%</span></section> <section><span>50%</span></section> <section><span>50%</span></section> <section><span>50%</span></section></article>
<hr>
<p><code>flex-shrink</code> disabled</p>
<article three> <section><span>50%</span></section> <section><span>50%</span></section> <section><span>50%</span></section> <section><span>50%</span></section></article>
Related Topics
How to Create a Box When Mouse Over Text in Pure CSS
How to Get a Three Column Layout with Twitter Bootstrap
Custom Svg Admin Menu Icon in Wordpress
What Are Good Web Development Fonts
Can Angular-Cli Remove Unused CSS
CSS Is Not Working in My Angular Component
CSS White Space at Bottom of Page Despite Having Both Min-Height and Height Tag
Prevent Wrapping of Menu Items
Style Using Nth-Child to Keep Table's Aspect (Alternating Row Colors) Updated
How Does CSS Formatting in a Google Maps Bubble Work
Realtime CSS/Scss Edition with Meteor Avoiding Server Restart
Select All Direct Descendant Dom Elements Regardless of Type
Vertically Aligning Text Next to a Radio Button
Getting Width of a Div Element
How to Change Link Color and Hover Color in Bootstrap Version 4