I'm trying to fill the vertical space of a flex item inside a Flexbox.
.container {_x000D_
height: 200px;_x000D_
width: 500px;_x000D_
display: flex;_x000D_
flex-direction: row;_x000D_
}_x000D_
.flex-1 {_x000D_
width: 100px;_x000D_
background-color: blue;_x000D_
}_x000D_
.flex-2 {_x000D_
position: relative;_x000D_
flex: 1;_x000D_
background-color: red;_x000D_
}_x000D_
.flex-2-child {_x000D_
height: 100%;_x000D_
width: 100%;_x000D_
background-color: green;_x000D_
}
_x000D_
<div class="container">_x000D_
<div class="flex-1"></div>_x000D_
<div class="flex-2">_x000D_
<div class="flex-2-child"></div>_x000D_
</div>_x000D_
</div>
_x000D_
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 inconvenientThis doesn't work in Chrome or Firefox currently.
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.
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;
}
fun fact: height-100% works in the latest chrome; but not in safari;
so solution in tailwind would be
https://tailwindcss.com/docs/align-items
and be applied recursively to the child's child's child ...
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.
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/
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;
}
_x000D_
<div class="container">
<div class="flex-1"></div>
<div class="flex-2">
<div class="flex-2-child"></div>
</div>
</div>
_x000D_
.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;
}
_x000D_
<div class="container">
<div class="flex-1"></div>
<div class="flex-2">
<div class="flex-2-child"></div>
</div>
</div>
_x000D_
.container { . . . . align-items: stretch; . . . . }
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.
position: relative;
on the parent of the child.position: absolute;
on the child.overflow-y: auto;
on the scrollable div.height: 0;
See this answer for more information on the scrolling issue.
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.
Source: Stackoverflow.com