How can I make Flexbox children 100% height of their parent?
CssFlexboxCss Problem Overview
I'm trying to fill the vertical space of a flex item inside a Flexbox.
.container {
height: 200px;
width: 500px;
display: flex;
flex-direction: row;
}
.flex-1 {
width: 100px;
background-color: blue;
}
.flex-2 {
position: relative;
flex: 1;
background-color: red;
}
.flex-2-child {
height: 100%;
width: 100%;
background-color: green;
}
<div class="container">
<div class="flex-1"></div>
<div class="flex-2">
<div class="flex-2-child"></div>
</div>
</div>
And here's the JSFiddle
flex-2-child
doesn't fill the required height except in the two cases where:
flex-2
has a height of 100% (which is weird because a flex item has a 100% by default + it is buggy in Chrome)flex-2-child
has a position absolute which is also inconvenient
This doesn't work in Chrome or Firefox currently.
Css Solutions
Solution 1 - Css
align-items: stretch
Use Similar to David Storey's answer, my workaround is:
.flex-2 {
display: flex;
align-items: stretch;
}
Note that height: 100%
should be removed from the child component (see comments).
Alternatively to align-items
, you can use align-self
just on the .flex-2-child
item you want stretched.
Solution 2 - Css
I have answered a similar question here.
I know you have already said position: absolute;
is inconvenient, but it works. See below for further information on fixing the resize issue.
Also see this jsFiddle for a demo, although I have only added WebKit prefixes so open in Chrome.
You basically have two issues which I will deal with separately.
- Getting the child of a flex-item to fill height 100%
- Set
position: relative;
on the parent of the child. - Set
position: absolute;
on the child. - You can then set width/height as required (100% in my sample).
- Fixing the resize scrolling "quirk" in Chrome
- Put
overflow-y: auto;
on the scrollable div. - The scrollable div must have an explicit height specified. My sample already has height 100%, but if none is already applied you can specify
height: 0;
See this answer for more information on the scrolling issue.
Solution 3 - Css
If I understand correctly, you want flex-2-child to fill the height and width of its parent, so that the red area is fully covered by the green?
If so, you just need to set flex-2 to use Flexbox:
.flex-2 {
display: flex;
}
Then tell flex-2-child to become flexible:
.flex-2-child {
flex: 1;
}
See http://jsfiddle.net/2ZDuE/10/
The reason is that flex-2-child is not a Flexbox item, but its parent is.
Solution 4 - Css
I suppose that Chrome's behavior is more consistent with the CSS specification (though it's less intuitive). According to Flexbox specification, the default stretch
value of align-self
property changes only the used value of the element's "cross size property" (height
, in this case). And, as I understand the CSS 2.1 specification, the percentage heights are calculated from the specified value of the parent's height
, not its used value. The specified value of the parent's height
isn't affected by any flex properties and is still auto
.
Setting an explicit height: 100%
makes it formally possible to calculate the percentage height of the child, just like setting height: 100%
to html
makes it possible to calculate the percentage height of body
in CSS 2.1.
Solution 5 - Css
I found the solution by myself. Suppose you have the CSS below:
.parent {
align-items: center;
display: flex;
justify-content: center;
}
.child {
height: 100%; <- didn't work
}
In this case, setting the height 100% will not work, so I set the margin-bottom
rule to auto
, like:
.child {
margin-bottom: auto;
}
And the child will be aligned to the topmost of the parent.
You can also use the align-self
rule anyway if you prefer:
.child {
align-self: flex-start;
}
Solution 6 - Css
This can also be solved with align-self: stretch;
on the element we want to be stretched.
Sometimes it is desirable to only stretch one item in a Flexbox setup.
.container {
height: 200px;
width: 500px;
display: flex;
flex-direction: row;
}
.flex-1 {
width: 100px;
background-color: blue;
}
.flex-2 {
position: relative;
flex: 1;
align-self: stretch;
background-color: red;
}
.flex-2-child {
background-color: green;
}
<div class="container">
<div class="flex-1"></div>
<div class="flex-2">
<div class="flex-2-child"></div>
</div>
</div>
Solution 7 - Css
<div class="container">
<div class="flex-1"></div>
<div class="flex-2">
<div class="flex-2-child"></div>
</div>
</div>
.container {
height: 200px;
width: 500px;
display: -moz-box;
display: -webkit-flexbox;
display: -ms-flexbox;
display: -webkit-flex;
display: -moz-flex;
display: flex;
-webkit-flex-direction: row;
-moz-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
}
.flex-1 {
flex:1 0 100px;
background-color: blue;
}
.flex-2 {
-moz-box-flex: 1;
-webkit-flex: 1;
-moz-flex: 1;
-ms-flex: 1;
flex: 1 0 100%;
background-color: red;
}
.flex-2-child {
flex: 1 0 100%;
height: 100%;
background-color: green;
}
Solution 8 - Css
An idea would be that display:flex;
with flex-direction: row;
is filling the container
div with .flex-1
and .flex-2
, but that does not mean that .flex-2
has a default height:100%;
, even if it is extended to full height.
And to have a child element (.flex-2-child
) with height:100%;
, you'll need to set the parent to height:100%;
or use display:flex;
with flex-direction: row;
on the .flex-2
div too.
From what I know, display:flex
will not extend all your child elements height to 100%.
A small demo, removed the height from .flex-2-child
and used display:flex;
on .flex-2
:
http://jsfiddle.net/2ZDuE/3/
Solution 9 - Css
fun fact: height-100% works in the latest chrome; but not in safari;
so solution in tailwind would be
"flex items-stretch"
https://tailwindcss.com/docs/align-items
and be applied recursively to the child's child's child ...
Solution 10 - Css
.parent {
display: flex;
}
.child {
min-height: 100%;
}
Solution 11 - Css
.container { . . . . align-items: stretch; . . . . }
Solution 12 - Css
This is my solution using css+.
First of all, if the first child (flex-1) should be 100px, it shouldn't be flex.
In css+ in fact you can set flexible and/or static elements (columns or rows) and your example become as easy as this:
<div class="container">
<div class="EXTENDER">
<div class="COLS">
<div class="CELL _100px" style="background-color:blue">100px</div>
<div class="CELL _FLEX" style="background-color:red">flex</div>
</div>
</div>
</div>
Container CSS:
.container {
height: 200px;
width: 500px;
position: relative;
}
And obviously include css+ 0.2 core.
Here is the fiddle.