How can I make Flexbox children 100% height of their parent?

CssFlexbox

Css 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:

  1. flex-2 has a height of 100% (which is weird because a flex item has a 100% by default + it is buggy in Chrome)
  2. 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

Use align-items: stretch

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.

  1. 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).
  1. 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;
}

http://jsfiddle.net/2ZDuE/750/

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRazView Question on Stackoverflow
Solution 1 - CssB TView Answer on Stackoverflow
Solution 2 - CssBrett PostinView Answer on Stackoverflow
Solution 3 - CssDavid StoreyView Answer on Stackoverflow
Solution 4 - CssIlya StreltsynView Answer on Stackoverflow
Solution 5 - Cssuser3896501View Answer on Stackoverflow
Solution 6 - CssGiorgosKView Answer on Stackoverflow
Solution 7 - CssCarol McKayView Answer on Stackoverflow
Solution 8 - Cssrmagnum2002View Answer on Stackoverflow
Solution 9 - CssArchy Will He 何魏奇View Answer on Stackoverflow
Solution 10 - CssZach WhiteView Answer on Stackoverflow
Solution 11 - CssHRKView Answer on Stackoverflow
Solution 12 - CssMarco AlloriView Answer on Stackoverflow