ChatGPT解决这个技术问题 Extra ChatGPT

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

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; }

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.

what is the problem with using height:100%; for .flex-2 ?
It defies the purpose of the flex item which is to fill the content by itself and it's giving me the weirdest bug in chrome where the height goes back to zero whenever I resize the window
Actually, the latest version of Firefox is the only one working properly
Currently, there are significant differences in behavior among browsers when it comes to rendering percentage heights in flexbox: stackoverflow.com/a/35537510/3597276
Yep, Chrome has some issues, especially with nested flexboxes. For example I've got a nested flex box with children that have height:100% but they are rendering with natural height instead. And the weird thing is if I change their height to auto, then they render as height:100% like I was trying to do. It is definitely not intuitive if that's how it should work.

B
B T

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.


stretch: this should be the chosen answer.
How would you align the text inside a div that has been stretched to vertically align in the middle tho?
Yes you should add removing height: 100%
This saved my day. I got a flex row which has some items. I want these items to take height from its parent. I demonstrated my issue here codepen.io/dshung1997/pen/LYxvXNy
Will this work if we have no control over "container" in this example? In other words, I can't make "container" use flex layout
P
Peter Mortensen

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.


Point 1) works perfectly in Chrome, Firefox doesn't need the position absolute.
This is not an acceptable solution. In all my years of programming I've learned you only use position absolute very carefully for some things, as elements may not render correctly in other browsers. Plus the answer isn't addressed, as he mentioned Flexbox right there in the Title, so this answer is wrong.
@MannyAlvarado this question and answer were posted at a time when flexbox was still in working draft and browser implementations all over the place. Historical context is important here. Thankfully we're in a better place now which is why better answers have surpassed this one.
P
Peter Mortensen

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.


How can I do the same, just with a height of 100% and every child is 50/50 ?
Be aware that if you use "align-items: center" you won't be able to use this fix since your items will now become equal-height.
@NeilMonroe You can still use align-items: center if you use align-self: stretch on just the one child.
Hi @David, i tried your solution, it works fine for the flex-direction: row layout, it seems not working with flex-direction: column layout, or i have any places wrong in the code. Could you help to check why in this fiddle jsfiddle.net/78o54Lmv, the inner box won't occupy the full height of its parent?
I have to add min-height: 100vh; to .flex-2 element to make it works. Thanks for the help!
P
Peter Mortensen

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.


Exactly! To put this into practice, just add height:100% to .flex-2. Here's the jsfiddle.
Chrome's behavior is more consistent with Chrome Team's interpretation of the CSS spec. While it could be interpreted that way, there are far better ways of interpreting it, any of which wouldn't have trapped us into this bazaar, annoying, and irksome behavior. They should have thought it through more.
@RickDoesburg, this was more than a year ago, but I believe that I had to resort to fixed height elements. I wish these browsers would get their act together. I'm really starting to dislike the mobile space.
Setting a child of a vertical flexbox container to height: 100% is giving very odd results for me in Chrome. It seems that this causes the "specified height" to be set to the total height of the container, rather than the height of the element itself, so causes unwanted scrolling when other elements have sizes calculated relative to it.
P
Peter Mortensen

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;
}

A nice hack, but the problem is: if child is a sidebar and it have a background color, the margin space is still white.
What's great about this solution is that the height of the parent can be dynamic! The previous solutions require the parent to have a set height. Thanks for this.
P
Peter Mortensen

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; }


c
corn on the cob

.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/


An explanation would be in order.
P
Peter Mortensen

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/


A
Archy Will He 何魏奇

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 ...


Z
Zach White
.parent {
    display: flex;
}

.child {
    min-height: 100%;
}

While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.
B
Berci

Another approach I used (other option wouldn't fit my case because I needed a more generic solution and I really want to avoid using position: absolute when possible):

Have a parent with display: flex Give your element display flex as well, align-self: stretch and margin-top: 0 + margin-bottom: 0

Minimal reproducible example:

.parrent { display:flex; // the width can be anything. width: 150px; } .full-height-just-with-bg-collor { width: 100%; display: flex; align-self: stretch; // this can be just 0 or you can set just the top and bottom values margin: 0 2px; background-color: green; }

textForHeight


H
HRK

.container { . . . . align-items: stretch; . . . . }


Welcome to stackoverflow. You need to fully explain your answer, and what it contributes that is different from the existing answers. See stackoverflow.com/help/how-to-answer
Your answer seems to be the same as B T's (written over three years early) but expressed far more poorly.
P
Peter Mortensen

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.