How does `flex-grow:0` get interpreted?
flex-grow:0
simply means that the item won't be resized during item size calculation to accommodate flex container's full main axis size.
Specification describes it as:
This
<number>
component setsflex-grow
longhand and specifies the flex grow factor, which determines how much the flex item will grow relative to the rest of the flex items in the flex container when positive free space is distributed. When omitted, it is set to1
.
I've emphasized main axis size above beacuse you should know that flex-grow
is related to main axis of the flex container which can be width or height dimension depending on flex-direction
and writing directionality of user browser.
Therefore we can't assume being equal to your assumption.
But when we're talking about flex-direction: row
and writing directionality LRTB (left to right, top to bottom) then they do work in the similar fashion as width: auto;
. Items do appear as inlined, but they still don't render the same because no whitespace is being added for each line break in HTML source as we normally see with usual inline elements.
How about width: 0
?
Flex item width is associated with flex-basis
property rather than grow factor. Although flex properties have precedence over width
or height
of items when grow and shrink factors are defined and non-zero.
Meaning of absolute values of flex-grow
Per the flexbox draft spec:
Flex values between 0 and 1 have a somewhat special behavior: when the sum of the flex values on the line is less than 1, they will take up less than 100% of the free space.
An item’s flex-grow value is effectively a request for some proportion of the free space, with 1 meaning “100% of the free space”; then if the items on the line are requesting more than 100% in total, the requests are rebalanced to keep the same ratio but use up exactly 100% of it. However, if the items request less than the full amount (such as three items that are each flex-grow: .25) then they’ll each get exactly what they request (25% of the free space to each, with the final 25% left unfilled). See § 9.7 Resolving Flexible Lengths for the exact details of how free space is distributed.
This pattern is required for continuous behavior as flex-grow approaches zero (which means the item wants none of the free space). Without this, a flex-grow: 1 item would take all of the free space; but so would a flex-grow: 0.1 item, and a flex-grow: 0.01 item, etc., until finally the value is small enough to underflow to zero and the item suddenly takes up none of the free space. With this behavior, the item instead gradually takes less of the free space as flex-grow shrinks below 1, smoothly transitioning to taking none of the free space at zero.
Unless this “partial fill” behavior is specifically what’s desired, authors should stick to values ≥ 1; for example, using 1 and 2 is usually better than using .33 and .67, as they’re more likely to behave as intended if items are added, removed, or line-wrapped.
In other words:
- if the total of all the
flex-grow
s is >= 1, all the remaining space will be distributed proportionate to the differentflex-grow
values. The actual values have no effect (e.g. 1:5 vs 2:10) as long as the proportions remain the same. - if the total is < 1, only part of the remaining space will be distributed in the same proportion -- the part represented by the total. For example, if all the
flex-grow
values add up to .13, only 13% of the remaining space will be distributed. (This can be seen in the code snippet in fnostro's answer).
The idea is that flex-grow: 0
(on a single item) takes up none of the remaining space, and flex-grow: 1
(or greater) takes up all of it; the values between 0 and 1 transition gradually between these two extremes. The same logic is applied when multiple items have a flex-grow
set.
And so, in the second snippet of the question, the flexbox child items will only take up .3 or 30% of the free space, not all of it.
What is this flex styling is doing in plain English?
The first value is the flex grow which is practically the size of the particular flex item relative to other flex items so if you give it a value of 2 the width will be two times the width of the remaining flex items. That is to say a flex grow of two where the width of a normal flex item is 20px will make that item 40px in size. The second value flex shrink does the opposite.
The third flex-basis means that that flex item will not go beyond that size it's more like min-width in flex box context. #cheers
What does flex: 1 mean?
Here is the explanation:
https://www.w3.org/TR/css-flexbox-1/#flex-common
flex: <positive-number>
Equivalent to flex: <positive-number> 1 0. Makes the flex item flexible and sets the flex basis to zero, resulting in an item that
receives the specified proportion of the free space in the flex
container. If all items in the flex container use this pattern, their
sizes will be proportional to the specified flex factor.
Therefore flex:1
is equivalent to flex: 1 1 0
with `flex-basis = 0` how does a flex sub-container decide what with it has
Here is a step by step illustration to understand the logic:
main {
display: flex;
flex-direction: column;
align-items: center;
background-color: hotpink;
margin:5px;
}
.flex-box {
display: flex;
background-color: gray;
}
.flex-box .box-1 {
/*flex: 1 1 0;*/
background-color: yellowgreen;
}
.flex-box .box-2 {
/*flex: 1 1 0
width: 100px; */
background-color: crimson;
}
We apply nothing and each element will take the width of its content without line break
<main>
<div class="flex-box">
<div class="box-1">
<p>Lorem, ipsum dolor si?</p>
</div>
<div class="box-2">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptas.</p>
</div>
</div>
</main>
We make the second item width:100px. it will shrink to that width and everything will remain centred
<main>
<div class="flex-box">
<div class="box-1">
<p>Lorem, ipsum dolor si?</p>
</div>
<div class="box-2" style="width:100px">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptas.</p>
</div>
</div>
</main>
Now the width of flex-box we have above will be the reference for the flex calculation and when we apply flex: 1 1 0 to both, then each one will get half that width
<main>
<div class="flex-box">
<div class="box-1" style="flex:1 1 0">
<p>Lorem, ipsum dolor si?</p>
</div>
<div class="box-2" style="width:100px;flex:1 1 0">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptas.</p>
</div>
</div>
</main>
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>
When does flex-grow switch to flex-shrink, and vice-versa?
The flex-basis
property sets the initial main size of the flex item, before free space is distributed by other flex properties.
This means that the flex item is first sized for its defined width (in flex-direction: row
) or height (in flex-direction: column
).
In other words, in a row-direction flex container, where flex-basis: 100px
is equivalent to width: 100px
, the item would have a width of 100px.
That's the initial main size.
THEN, other flex properties are applied. Namely, flex-grow
and flex-shrink
.
If the container is wider than 100px, then flex-grow: 1
expands the item to fill the extra space.
If the container is less than 100px, then flex-grow: 1
is ignored and flex-shrink: 1
reduces the size of the item according to a flex sizing algorithm.
So, to answer your question:
When does flex switch from grow to shrink?
Assuming both properties are enabled (i.e., they are not flex-grow: 0
or flex-shrink: 0
), the switch will occur when the sum total of flex-basis
/ width
/ height
on flex items is no longer less or more than the length of the container.
To make this a bit more clear:
When the sum total of
flex-basis
/width
/height
on flex items is no longer more than the length of the container, this means there is no overflow and the items don't consume all available space.flex-grow
works.When the sum total of
flex-basis
/width
/height
on flex items is no longer less than the length of the container, this means there is overflow and the items must shrink to fit inside the container.flex-shrink
works.
From the spec:
flex-grow
This [property] specifies the flex grow factor, which determines how much the flex item will grow relative to the rest of
the flex items in the flex container when positive free space is
distributed.
flex-shrink
This [property] specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex
items in the flex container when negative free space is distributed.
flex-basis
This [property] specifies the initial main size of the flex item,
before free space is distributed according to the flex factors.https://www.w3.org/TR/css-flexbox-1/#flex-property
How is element width calculated with flex-grow?
You will have 330px
of free space (900 - 450 - 120
). The first element will grow twice than the second one. The total grow factor is 3
(2+1
) so the first one will take 2/3*330 = 220px
and the second one 1/3*330px = 110px
and we will end with
article = 120px + 220px = 340px
aside = 450px + 110px = 560px
Inspect the below code to validate the values:
div {
width: 900px;
display: flex;
height: 50px;
}
article {
flex-grow: 2;
width: 120px;
background: red;
}
aside {
flex-grow: 1;
width: 450px;
background: green;
}
<div>
<article></article>
<aside></aside>
</div>
flex child is growing out of parent
Solution #1 - Without Scroll
Instead of flex: 1 0 auto
on the video container, just use flex: 1
. This sizes the item based on available space, not the intrinsic height of the content.
Then, because flex items cannot be smaller than the size of their content – min-height: auto
is the default – add min-height: 0
to allow the item to shrink to fit inside the container.
.box-grow {
flex: 1; /* formerly flex: 1 0 auto; */
background: green;
padding: 5px;
margin: 5px;
min-height: 0; /* new */
}
.my-box { height: 300px; width: 600px; background: red; padding: 5px;}.content-box { background: blue;}.col { display: flex; flex-direction: column; justify-content: space-between}.box-shrink { flex: 0 1 auto; background: green; padding: 5px; margin: 5px;}.box-grow { flex: 1; /* formerly flex: 1 0 auto; */ background: green; padding: 5px; margin: 5px; min-height: 0; /* new */}video { max-height: 100%; max-width: 100%; margin: auto; display: block;}
<div class="my-box col"> <div class="box-shrink"> small sized static content </div> <div class="content-box box-grow"> <video controls> <source src="http://techslides.com/demos/sample-videos/small.webm" type="video/webm"> </video> </div> <div class="box-shrink"> small sized static content </div></div>
Related Topics
Adding CSS Class to Multiple Elements
How to Make Custom Scrollbars Show in All Browsers
Bootstrap Container with Position:Absolute Loses Layout Inside
Resizing Buttons in Twitter-Bootstrap
How to Use > or < (Greater Than and Less Than ) Symbols in Media Queries
Align Text Baseline with a Button in CSS
Why Do I Have to Add "Overflow:Hidden" to Make The Navigation Bar Visible on The Page
Make Flex Item Full Width After It's Been Wrapped Without Using Media Queries
Make Some Gradient Move Endlessly in a Progress Bar Like in Windows 7
CSS Table Border Spacing Inside Only
Styling Overlapping Annotations in Text with HTML <Span> Tags and CSS
Div with Margin-Left and Width:100% Overflowing on The Right Side
Phantomjs Doesn't Render Footers with a Custom Styles
Tailwind CSS How to Code Pixel Perfect Design
Using Container-Fluid Within Bootstrap Cause Horizontal Scrollbar