Make flex-grow expand items based on their original size
Short Answer
Switch from flex: 1
to flex: auto
.
Explanation
The flex-grow
property factors in two key pieces of data:
- The free space in the row / column where it is being used.
- The value of the
flex-basis
property.
Distribution of Free Space
The flex-grow
property distributes free space in the container among flex items in the same line.
If there is no free space, flex-grow
has no effect.
If there is negative free space (i.e., the total length of flex items is greater than the length of the container), then flex-grow
has no effect and flex-shrink
comes into play.
The flex-basis
factor
When flex-basis
is 0
, flex-grow
ignores the size of the content in flex items and treats all space on the line as free space.
This is absolute sizing. All space on the line is distributed.
When flex-basis
is auto
, the size of the content in flex items is first deducted to determine the free space in each item. flex-grow
then distributes the free space among items (based on each item's flex-grow
value).
This is relative sizing. Only extra space on the line is distributed.
Here's an illustration from the spec:
Examples:
flex: 1
(absolute sizing)
This shorthand rule breaks down to: flex-grow: 1
/ flex-shrink: 1
/ flex-basis: 0
Applied to all flex items, this will make them equal length, regardless of content. (Note that in some cases an override of default minimum sizing will be necessary for this effect to occur.)
flex-grow: 1
(relative sizing)
This rule by itself will factor in both content size and available space, because the default value for flex-basis
is auto
.
flex: auto
(relative sizing)
This shorthand factors in both content size and available space because it breaks down to:
flex-grow: 1
flex-shrink: 1
flex-basis: auto
More variations here: 7.1.1. Basic Values of flex
additional keywords for search: difference between flex-basis auto 0 flex 1 auto
flex items not expanding or shrinking with flex-grow
There are two pieces missing in this puzzle.
You have the column widths set to
flex-grow: 1
. This means thatflex-basis
is still at its default value,auto
(content-based). So the column is sized based on the image size. You can addflex-basis: 0
, or just useflex: 1
.Full explanation: Make flex-grow expand items based on their original size
Flex items, by default, cannot shrink below the size of their content. Their initial setting is
min-width: auto
. You need to override this default withmin-width: 0
.Full explanation: Why don't flex items shrink past content size?
.row {
display: flex;
height: 100vh;
}
.column {
min-width: 0; /* new */
flex: 1; /* adjustment */
border: 2px solid #000;
transition: all 300ms ease-in-out;
}
.column:hover {
flex-grow: 4.3;
}
body {
margin: 0;
}
<div class="row">
<div class="column">
<img src="https://images.pexels.com/photos/2194261/pexels-photo-2194261.jpeg">
</div>
<div class="column">
<img src="https://images.pexels.com/photos/1276553/pexels-photo-1276553.jpeg">
</div>
<div class="column">
<img src="https://images.pexels.com/photos/774731/pexels-photo-774731.jpeg">
</div>
</div>
Make flex item grow past (larger) than flex container
Maybe I have not understand well your problem. When I tried on JsFiddle, I have the result you seem to wish. Element hovered is bigger than the parent element "row".
.row{
position: relative;
display: flex;
background: blue;
}
.cards{
width: 50px;
height: 50px;
background: red;
margin: 10px;
}
.cards:hover{
transform: scale(1.5);
}
<div class="row">
<div class="cards">1</div>
<div class="cards">1</div>
<div class="cards">1</div>
</div>
https://jsfiddle.net/nesquimo/vbb8td62/1/
How can I allow flex-items to grow while keeping the same size?
This is something that cannot be expressed via CSS Flexbox right now. Someone asked basically this exact question on the CSS Working Group Mailing List a few days ago, and the response was: "At the moment, no, this is not possible. This is a high-priority item for Flexbox 2, though.
You may be able to hack up something like you want using max-width
, though -- that'll prevent flex items (particularly those on the last line) from growing indefinitely. Here's a forked version of your plunk with a nonzero flex-grow, and with max-width: 10em
.
(I chose 10em
arbitrarily; you could also use e.g. max-width: calc(100%/5)
, if you want to make sure each flex item takes up no more than 1/5 of the line, for example.)
Make flex items have equal width in a row
Flexbox method
In order to make the text items (.section-child
) equal width, you need to use flex: 1 1 0
, which you have done. This is the same as saying flex: 1
.
However, this by itself doesn't achieve the goal for two reasons:
The parent of
.section-child
, a flex container, but also a flex item in a larger container, is limited to the width of its content, by default. So it won't expand and the text can overflow the container. You need to applyflex: 1
to.section
, as well.A flex item cannot be smaller than the size of its content, by default. The initial setting is
min-width: auto
. Soflex: 1
cannot work to equally distribute container space, because a flex item cannot shrink past the longest item. You need to override this behavior withmin-width: 0
.
.top-level { display: flex; flex-flow: row wrap;}
.section { display: flex; flex-flow: row nowrap; border: 1px solid; margin-right: 12px; margin-top: 12px; flex: 1; min-width: 0;}
.section-child { display: flex; flex-flow: column nowrap; align-items: center; flex: 1; min-width: 0;}
.child-title { white-space: nowrap;}
.vertical-separator { width: 1px; background-color: rgba(0, 0, 0, 0.3); margin: 8px;}
<div class="top-level"> <section class="section"> <div class="section-child"> <h4 class="child-title">Title</h4> <!--A lot more content here--> </div> <div class="vertical-separator"></div> <div class="section-child"> <h4 class="child-title">Longer title</h4> <!--A lot more content here--> </div> <div class="vertical-separator"></div> <div class="section-child"> <h4 class="child-title">Much much longer title</h4> <!--A lot more content here--> </div> </section> <section class="section"> <div class="section-child"> <h4 class="child-title">Title</h4> <!--A lot more content here--> </div> <div class="vertical-separator"></div> <div class="section-child"> <h4 class="child-title">Longer title</h4> <!--A lot more content here--> </div> <div class="vertical-separator"></div> <div class="section-child"> <h4 class="child-title">Much much longer title</h4> <!--A lot more content here--> </div> </section> <section class="section"> <div class="section-child"> <h4 class="child-title">Title</h4> <!--A lot more content here--> </div> <div class="vertical-separator"></div> <div class="section-child"> <h4 class="child-title">Longer title</h4> <!--A lot more content here--> </div> <div class="vertical-separator"></div> <div class="section-child"> <h4 class="child-title">Much much longer title</h4> <!--A lot more content here--> </div> </section></div>
Fill the remaining height or width in a flex container
Use the flex-grow
property to make a flex item consume free space on the main axis.
This property will expand the item as much as possible, adjusting the length to dynamic environments, such as screen re-sizing or the addition / removal of other items.
A common example is flex-grow: 1
or, using the shorthand property, flex: 1
.
Hence, instead of width: 96%
on your div, use flex: 1
.
You wrote:
So at the moment, it's set to 96% which looks OK until you really squash the screen - then the right hand div gets a bit starved of the space it needs.
The squashing of the fixed-width div is related to another flex property: flex-shrink
By default, flex items are set to flex-shrink: 1
which enables them to shrink in order to prevent overflow of the container.
To disable this feature use flex-shrink: 0
.
For more details see The flex-shrink
factor section in the answer here:
- What are the differences between flex-basis and width?
Learn more about flex alignment along the main axis here:
- In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
Learn more about flex alignment along the cross axis here:
- How does flex-wrap work with align-self, align-items and align-content?
How to create a flex item that shrinks before it wraps?
The problem is not flex-shrink
. The problem is flex-basis
. You have it set to 50%.
This means that flex-grow
will add free space to the flex-basis
, and each item will wrap quickly, before it has an opportunity to shrink.
Switch from flex-basis: 50%
to flex-basis: 0
.
More specifically, instead of flex: 1 1 50%
use flex: 1
, which breaks down to this:
flex-grow: 1
flex-shrink: 1
flex-basis: 0
Now flex-grow
distributes free space equally – not proportionally – to both items, and they can shrink before they wrap.
(Here's a more in-depth explanation: Make flex-grow expand items based on their original size)
.m { display: flex; flex-wrap: wrap;}
.l_1 { background-color: red; flex: 1;}
.r_1 { background-color: yellow; flex: 1;}
<div class=m> <div class=l_1>left_______________________________________________X</div> <div class=r_1>right</div></div>
How to make flexbox items the same size?
Set them so that their flex-basis
is 0
(so all elements have the same starting point), and allow them to grow:
flex: 1 1 0px
Your IDE or linter might mention that the unit of measure 'px' is redundant
. If you leave it out (like: flex: 1 1 0
), IE will not render this correctly. So the px
is required to support Internet Explorer, as mentioned in the comments by @fabb;
Make one item of a flexbox half or a quarter size of other items
Trying flex: .5 1 0
should work. That should size it the way you want.
Related Topics
Stretch Child Div Height to Fill Parent That Has Dynamic Height
Why Does Order of Transforms Matter? Rotate/Scale Doesn't Give the Same Result as Scale/Rotate
Mvc4 Stylebundle Not Resolving Images
Css 3 Slide-In from Left Transition
Vertical Align Middle in ≪Div≫
How to Set Opacity in Parent Div and Not Affect in Child Div
Areas Covered by Flexbox Which Are Difficult or Impossible to Achieve With Grid
Css Attribute Selectors: the Rules on Quotes (", ' or None)
Matching an Empty Input Box Using Css
How to Add Border in My Clip-Path: Polygon(); CSS Style
Css3 Gradient Background Set on Body Doesn't Stretch But Instead Repeats
Any Recommendations For a CSS Minifier
How to Hide Collapsible Bootstrap Navbar on Click
Google Chrome Printing Page Breaks
Justify the Last Line of a Div